Merge branch 'master' of git.freeswitch.org:freeswitch

This commit is contained in:
Brian West 2010-08-17 10:16:57 -05:00
commit 5c93d44094
603 changed files with 87561 additions and 26341 deletions

View File

@ -933,6 +933,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_opal", "src\mod\endpoin
{202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_h323", "src\mod\endpoints\mod_h323\mod_h323_2008.vcproj", "{05C9FB27-480E-4D53-B3B7-7338E2514666}"
ProjectSection(ProjectDependencies) = postProject
{202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_skinny", "src\mod\endpoints\mod_skinny\mod_skinny_2008.vcproj", "{CC1DD008-9406-448D-A0AD-33C3186CFADB}"
ProjectSection(ProjectDependencies) = postProject
{202D7A4E-760D-4D0E-AFA1-D7459CED30FF} = {202D7A4E-760D-4D0E-AFA1-D7459CED30FF}
@ -1101,6 +1106,26 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_hash", "src\mod\applica
{CF405366-9558-4AE8-90EF-5E21B51CCB4E} = {CF405366-9558-4AE8-90EF-5E21B51CCB4E}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download OPENSSL", "libs\win32\Download OPENSSL.2008.vcproj", "{D578E676-7EC8-4548-BD8B-845C635F14AD}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "openssl", "openssl", "{B376D494-D7DD-4B2A-99E2-52916D5A8CD8}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libeay32", "libs\win32\openssl\libeay32.2008.vcproj", "{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}"
ProjectSection(ProjectDependencies) = postProject
{D578E676-7EC8-4548-BD8B-845C635F14AD} = {D578E676-7EC8-4548-BD8B-845C635F14AD}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ssleay32", "libs\win32\openssl\ssleay32.2008.vcproj", "{B4B62169-5AD4-4559-8707-3D933AC5DB39}"
ProjectSection(ProjectDependencies) = postProject
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE} = {D331904D-A00A-4694-A5A3-FCFF64AB5DBE}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "openssl", "libs\win32\openssl\openssl.2008.vcproj", "{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}"
ProjectSection(ProjectDependencies) = postProject
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE} = {D331904D-A00A-4694-A5A3-FCFF64AB5DBE}
{B4B62169-5AD4-4559-8707-3D933AC5DB39} = {B4B62169-5AD4-4559-8707-3D933AC5DB39}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
All|Win32 = All|Win32
@ -2380,6 +2405,13 @@ Global
{05C9FB27-480E-4D53-B3B7-6338E2526666}.Debug|x64.ActiveCfg = Debug|Win32
{05C9FB27-480E-4D53-B3B7-6338E2526666}.Release|Win32.ActiveCfg = Release|Win32
{05C9FB27-480E-4D53-B3B7-6338E2526666}.Release|x64.ActiveCfg = Release|Win32
{05C9FB27-480E-4D53-B3B7-7338E2514666}.All|Win32.ActiveCfg = Release|Win32
{05C9FB27-480E-4D53-B3B7-7338E2514666}.All|Win32.Build.0 = Release|Win32
{05C9FB27-480E-4D53-B3B7-7338E2514666}.All|x64.ActiveCfg = Release|Win32
{05C9FB27-480E-4D53-B3B7-7338E2514666}.Debug|Win32.ActiveCfg = Debug|Win32
{05C9FB27-480E-4D53-B3B7-7338E2514666}.Debug|x64.ActiveCfg = Debug|Win32
{05C9FB27-480E-4D53-B3B7-7338E2514666}.Release|Win32.ActiveCfg = Release|Win32
{05C9FB27-480E-4D53-B3B7-7338E2514666}.Release|x64.ActiveCfg = Release|Win32
{CC1DD008-9406-448D-A0AD-33C3186CFADB}.All|Win32.ActiveCfg = Release|Win32
{CC1DD008-9406-448D-A0AD-33C3186CFADB}.All|x64.ActiveCfg = Release|Win32
{CC1DD008-9406-448D-A0AD-33C3186CFADB}.Debug|Win32.ActiveCfg = Debug|Win32
@ -2774,6 +2806,50 @@ Global
{2E250296-0C08-4342-9C8A-BCBDD0E7DF65}.Release|Win32.Build.0 = Release|Win32
{2E250296-0C08-4342-9C8A-BCBDD0E7DF65}.Release|x64.ActiveCfg = Release|x64
{2E250296-0C08-4342-9C8A-BCBDD0E7DF65}.Release|x64.Build.0 = Release|x64
{D578E676-7EC8-4548-BD8B-845C635F14AD}.All|Win32.ActiveCfg = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.All|Win32.Build.0 = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.All|x64.ActiveCfg = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Debug|Win32.ActiveCfg = Debug|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Debug|Win32.Build.0 = Debug|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Debug|x64.ActiveCfg = Debug|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Debug|x64.Build.0 = Debug|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Release|Win32.ActiveCfg = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Release|Win32.Build.0 = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Release|x64.ActiveCfg = Release|Win32
{D578E676-7EC8-4548-BD8B-845C635F14AD}.Release|x64.Build.0 = Release|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.All|Win32.ActiveCfg = Release|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.All|Win32.Build.0 = Release|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.All|x64.ActiveCfg = Release|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Debug|Win32.ActiveCfg = Debug|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Debug|Win32.Build.0 = Debug|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Debug|x64.ActiveCfg = Debug|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Debug|x64.Build.0 = Debug|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Release|Win32.ActiveCfg = Release|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Release|Win32.Build.0 = Release|Win32
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Release|x64.ActiveCfg = Release|x64
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE}.Release|x64.Build.0 = Release|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.All|Win32.ActiveCfg = Release|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.All|Win32.Build.0 = Release|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.All|x64.ActiveCfg = Release|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Debug|Win32.ActiveCfg = Debug|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Debug|Win32.Build.0 = Debug|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Debug|x64.ActiveCfg = Debug|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Debug|x64.Build.0 = Debug|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Release|Win32.ActiveCfg = Release|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Release|Win32.Build.0 = Release|Win32
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Release|x64.ActiveCfg = Release|x64
{B4B62169-5AD4-4559-8707-3D933AC5DB39}.Release|x64.Build.0 = Release|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.All|Win32.ActiveCfg = Release|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.All|Win32.Build.0 = Release|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.All|x64.ActiveCfg = Release|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Debug|Win32.ActiveCfg = Debug|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Debug|Win32.Build.0 = Debug|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Debug|x64.ActiveCfg = Debug|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Debug|x64.Build.0 = Debug|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Release|Win32.ActiveCfg = Release|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Release|Win32.Build.0 = Release|Win32
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Release|x64.ActiveCfg = Release|x64
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -2794,6 +2870,7 @@ Global
{0DF3ABD0-DDC0-4265-B778-07C66780979B} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C}
{B3F424EC-3D8F-417C-B244-3919D5E1A577} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C}
{05C9FB27-480E-4D53-B3B7-6338E2526666} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C}
{05C9FB27-480E-4D53-B3B7-7338E2514666} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C}
{CC1DD008-9406-448D-A0AD-33C3186CFADB} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C}
{C6E78A4C-DB1E-47F4-9B63-4DC27D86343F} = {9460B5F1-0A95-41C4-BEB7-9C2C96459A7C}
{30A5B29C-983E-4580-9FD0-D647CCDCC7EB} = {E72B5BCB-6462-4D23-B419-3AF1A4AC3D78}
@ -2892,6 +2969,7 @@ Global
{ABB71A76-42B0-47A4-973A-42E3D920C6FD} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{9778F1C0-09BC-4698-8EBC-BD982247209A} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{56B91D01-9150-4BBF-AFA1-5B68AB991B76} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{B376D494-D7DD-4B2A-99E2-52916D5A8CD8} = {EB910B0D-F27D-4B62-B67B-DE834C99AC5B}
{8B3B4C4C-13C2-446C-BEB0-F412CC2CFB9A} = {C120A020-773F-4EA3-923F-B67AF28B750D}
{4F92B672-DADB-4047-8D6A-4BB3796733FD} = {C120A020-773F-4EA3-923F-B67AF28B750D}
{2DEE4895-1134-439C-B688-52203E57D878} = {C120A020-773F-4EA3-923F-B67AF28B750D}
@ -2909,6 +2987,7 @@ Global
{E10571C4-E7F4-4608-B5F2-B22E7EB95400} = {C120A020-773F-4EA3-923F-B67AF28B750D}
{FFF82F9B-6A2B-4BE3-95D8-DC5A4FC71E19} = {C120A020-773F-4EA3-923F-B67AF28B750D}
{B808178B-82F0-4CF4-A2B1-921939FA24D0} = {C120A020-773F-4EA3-923F-B67AF28B750D}
{D578E676-7EC8-4548-BD8B-845C635F14AD} = {C120A020-773F-4EA3-923F-B67AF28B750D}
{988CACF7-3FCB-4992-BE69-77872AE67DC8} = {6CD61A1D-797C-470A-BE08-8C31B68BB336}
{5BC072DB-3826-48EA-AF34-FE32AA01E83B} = {6CD61A1D-797C-470A-BE08-8C31B68BB336}
{FA429E98-8B03-45E6-A096-A4BC5E821DE4} = {6CD61A1D-797C-470A-BE08-8C31B68BB336}
@ -2978,5 +3057,8 @@ Global
{504B3154-7A4F-459D-9877-B951021C3F1F} = {62F27B1A-C919-4A70-8478-51F178F3B18F}
{746F3632-5BB2-4570-9453-31D6D58A7D8E} = {62F27B1A-C919-4A70-8478-51F178F3B18F}
{DEB01ACB-D65F-4A62-AED9-58C1054499E9} = {62F27B1A-C919-4A70-8478-51F178F3B18F}
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE} = {B376D494-D7DD-4B2A-99E2-52916D5A8CD8}
{B4B62169-5AD4-4559-8707-3D933AC5DB39} = {B376D494-D7DD-4B2A-99E2-52916D5A8CD8}
{25BD39B1-C8BF-4676-A738-9CABD9C6BC79} = {B376D494-D7DD-4B2A-99E2-52916D5A8CD8}
EndGlobalSection
EndGlobal

View File

@ -575,7 +575,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_say_zh", "src\mod\say\m
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mod_managed", "src\mod\languages\mod_managed\mod_managed.2010.vcxproj", "{7B42BDA1-72C0-4378-A9B6-5C530F8CD61E}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSWITCH.Managed", "src\mod\languages\mod_managed\managed\FreeSWITCH.Managed.2010.csproj", "{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FreeSWITCH.Managed.2010", "src\mod\languages\mod_managed\managed\FreeSWITCH.Managed.2010.csproj", "{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Download mpg123", "libs\win32\Download mpg123.2010.vcxproj", "{E796E337-DE78-4303-8614-9A590862EE95}"
EndProject
@ -832,11 +832,9 @@ Global
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Debug|Win32.ActiveCfg = Debug|Win32
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Debug|Win32.Build.0 = Debug|Win32
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Debug|x64.ActiveCfg = Debug|x64
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Debug|x64.Build.0 = Debug|x64
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|Win32.ActiveCfg = Release|Win32
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|Win32.Build.0 = Release|Win32
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|x64.ActiveCfg = Release|x64
{1AD3F51E-BBB6-4090-BA39-9DFAB1EF1F5F}.Release|x64.Build.0 = Release|x64
{692F6330-4D87-4C82-81DF-40DB5892636E}.All|Win32.ActiveCfg = Release|x64
{692F6330-4D87-4C82-81DF-40DB5892636E}.All|x64.ActiveCfg = Release|x64
{692F6330-4D87-4C82-81DF-40DB5892636E}.All|x64.Build.0 = Release|x64
@ -1148,22 +1146,18 @@ Global
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Debug|Win32.ActiveCfg = Debug|Win32
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Debug|Win32.Build.0 = Debug|Win32
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Debug|x64.ActiveCfg = Debug|x64
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Debug|x64.Build.0 = Debug|x64
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Release|Win32.ActiveCfg = Release|Win32
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Release|Win32.Build.0 = Release|Win32
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Release|x64.ActiveCfg = Release|x64
{ACFFF684-4D19-4D48-AF12-88EA1D778BDF}.Release|x64.Build.0 = Release|x64
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.All|Win32.ActiveCfg = Release|x64
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.All|x64.ActiveCfg = Release|x64
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.All|x64.Build.0 = Release|x64
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Debug|Win32.ActiveCfg = Debug|Win32
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Debug|Win32.Build.0 = Debug|Win32
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Debug|x64.ActiveCfg = Debug|x64
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Debug|x64.Build.0 = Debug|x64
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Release|Win32.ActiveCfg = Release|Win32
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Release|Win32.Build.0 = Release|Win32
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Release|x64.ActiveCfg = Release|x64
{8F992C49-6C51-412F-B2A3-34EAB708EB65}.Release|x64.Build.0 = Release|x64
{4043FC6A-9A30-4577-8AD5-9B233C9575D8}.All|Win32.ActiveCfg = Release|x64
{4043FC6A-9A30-4577-8AD5-9B233C9575D8}.All|x64.ActiveCfg = Release|x64
{4043FC6A-9A30-4577-8AD5-9B233C9575D8}.All|x64.Build.0 = Release|x64
@ -1192,11 +1186,9 @@ Global
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Debug|Win32.ActiveCfg = Debug|Win32
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Debug|Win32.Build.0 = Debug|Win32
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Debug|x64.ActiveCfg = Debug|x64
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Debug|x64.Build.0 = Debug|x64
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Release|Win32.ActiveCfg = Release|Win32
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Release|Win32.Build.0 = Release|Win32
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Release|x64.ActiveCfg = Release|x64
{0A6B5EA5-6E9B-4A51-931F-ED25AA87B4DF}.Release|x64.Build.0 = Release|x64
{AB91A099-7690-4ECF-8994-E458F4EA1ED4}.All|Win32.ActiveCfg = Release|x64
{AB91A099-7690-4ECF-8994-E458F4EA1ED4}.All|x64.ActiveCfg = Release|x64
{AB91A099-7690-4ECF-8994-E458F4EA1ED4}.All|x64.Build.0 = Release|x64
@ -1291,11 +1283,9 @@ Global
{028C7278-05D7-4E18-82FE-BE231B844F41}.Debug|Win32.ActiveCfg = Debug|Win32
{028C7278-05D7-4E18-82FE-BE231B844F41}.Debug|Win32.Build.0 = Debug|Win32
{028C7278-05D7-4E18-82FE-BE231B844F41}.Debug|x64.ActiveCfg = Debug|x64
{028C7278-05D7-4E18-82FE-BE231B844F41}.Debug|x64.Build.0 = Debug|x64
{028C7278-05D7-4E18-82FE-BE231B844F41}.Release|Win32.ActiveCfg = Release|Win32
{028C7278-05D7-4E18-82FE-BE231B844F41}.Release|Win32.Build.0 = Release|Win32
{028C7278-05D7-4E18-82FE-BE231B844F41}.Release|x64.ActiveCfg = Release|x64
{028C7278-05D7-4E18-82FE-BE231B844F41}.Release|x64.Build.0 = Release|x64
{D7F1E3F2-A3F4-474C-8555-15122571AF52}.All|Win32.ActiveCfg = Release|x64
{D7F1E3F2-A3F4-474C-8555-15122571AF52}.All|x64.ActiveCfg = Release|x64
{D7F1E3F2-A3F4-474C-8555-15122571AF52}.All|x64.Build.0 = Release|x64
@ -1456,11 +1446,9 @@ Global
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Debug|Win32.ActiveCfg = Debug|Win32
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Debug|Win32.Build.0 = Debug|Win32
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Debug|x64.ActiveCfg = Debug|x64
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Debug|x64.Build.0 = Debug|x64
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Release|Win32.ActiveCfg = Release|Win32
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Release|Win32.Build.0 = Release|Win32
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Release|x64.ActiveCfg = Release|x64
{36E854E3-CE12-4348-A125-CCF3F9D74813}.Release|x64.Build.0 = Release|x64
{7B077E7F-1BE7-4291-AB86-55E527B25CAC}.All|Win32.ActiveCfg = Release|x64
{7B077E7F-1BE7-4291-AB86-55E527B25CAC}.All|x64.ActiveCfg = Release|x64
{7B077E7F-1BE7-4291-AB86-55E527B25CAC}.All|x64.Build.0 = Release|x64
@ -1609,18 +1597,18 @@ Global
{7A8D8174-B355-4114-AFC1-04777CB9DE0A}.All|x64.Build.0 = Release|Win32
{7A8D8174-B355-4114-AFC1-04777CB9DE0A}.Debug|Win32.ActiveCfg = Debug|Win32
{7A8D8174-B355-4114-AFC1-04777CB9DE0A}.Debug|Win32.Build.0 = Debug|Win32
{7A8D8174-B355-4114-AFC1-04777CB9DE0A}.Debug|x64.ActiveCfg = Debug|Win32
{7A8D8174-B355-4114-AFC1-04777CB9DE0A}.Debug|x64.Build.0 = Debug|Win32
{7A8D8174-B355-4114-AFC1-04777CB9DE0A}.Debug|x64.ActiveCfg = Debug|x64
{7A8D8174-B355-4114-AFC1-04777CB9DE0A}.Debug|x64.Build.0 = Debug|x64
{7A8D8174-B355-4114-AFC1-04777CB9DE0A}.Release|Win32.ActiveCfg = Release|Win32
{7A8D8174-B355-4114-AFC1-04777CB9DE0A}.Release|Win32.Build.0 = Release|Win32
{7A8D8174-B355-4114-AFC1-04777CB9DE0A}.Release|x64.ActiveCfg = Release|Win32
{7A8D8174-B355-4114-AFC1-04777CB9DE0A}.Release|x64.Build.0 = Release|Win32
{7A8D8174-B355-4114-AFC1-04777CB9DE0A}.Release|x64.ActiveCfg = Release|x64
{7A8D8174-B355-4114-AFC1-04777CB9DE0A}.Release|x64.Build.0 = Release|x64
{7EB71250-F002-4ED8-92CA-CA218114537A}.All|Win32.ActiveCfg = Release|Win32
{7EB71250-F002-4ED8-92CA-CA218114537A}.All|x64.ActiveCfg = Release|Win32
{7EB71250-F002-4ED8-92CA-CA218114537A}.Debug|Win32.ActiveCfg = Debug|Win32
{7EB71250-F002-4ED8-92CA-CA218114537A}.Debug|x64.ActiveCfg = Debug|Win32
{7EB71250-F002-4ED8-92CA-CA218114537A}.Debug|x64.ActiveCfg = Debug|x64
{7EB71250-F002-4ED8-92CA-CA218114537A}.Release|Win32.ActiveCfg = Release|Win32
{7EB71250-F002-4ED8-92CA-CA218114537A}.Release|x64.ActiveCfg = Release|Win32
{7EB71250-F002-4ED8-92CA-CA218114537A}.Release|x64.ActiveCfg = Release|x64
{6E49F6C2-ADDA-4BFB-81FE-AB9AF51B455F}.All|Win32.ActiveCfg = Release|Win32
{6E49F6C2-ADDA-4BFB-81FE-AB9AF51B455F}.All|x64.ActiveCfg = Release|Win32
{6E49F6C2-ADDA-4BFB-81FE-AB9AF51B455F}.Debug|Win32.ActiveCfg = Debug|Win32
@ -1630,9 +1618,9 @@ Global
{464AAB78-5489-4916-BE51-BF8D61822311}.All|Win32.ActiveCfg = Release|Win32
{464AAB78-5489-4916-BE51-BF8D61822311}.All|x64.ActiveCfg = Release|Win32
{464AAB78-5489-4916-BE51-BF8D61822311}.Debug|Win32.ActiveCfg = Debug|Win32
{464AAB78-5489-4916-BE51-BF8D61822311}.Debug|x64.ActiveCfg = Debug|Win32
{464AAB78-5489-4916-BE51-BF8D61822311}.Debug|x64.ActiveCfg = Debug|x64
{464AAB78-5489-4916-BE51-BF8D61822311}.Release|Win32.ActiveCfg = Release|Win32
{464AAB78-5489-4916-BE51-BF8D61822311}.Release|x64.ActiveCfg = Release|Win32
{464AAB78-5489-4916-BE51-BF8D61822311}.Release|x64.ActiveCfg = Release|x64
{0AD1177E-1FD8-4643-9391-431467A11084}.All|Win32.ActiveCfg = Release|x64
{0AD1177E-1FD8-4643-9391-431467A11084}.All|x64.ActiveCfg = Release|x64
{0AD1177E-1FD8-4643-9391-431467A11084}.All|x64.Build.0 = Release|x64
@ -1781,9 +1769,11 @@ Global
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Debug|Win32.ActiveCfg = Debug|Any CPU
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Debug|Win32.Build.0 = Debug|Any CPU
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Debug|x64.ActiveCfg = Debug|Any CPU
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Debug|x64.Build.0 = Debug|Any CPU
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Release|Win32.ActiveCfg = Release|Any CPU
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Release|Win32.Build.0 = Release|Any CPU
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Release|x64.ActiveCfg = Release|Any CPU
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0}.Release|x64.Build.0 = Release|Any CPU
{E796E337-DE78-4303-8614-9A590862EE95}.All|Win32.ActiveCfg = Release|Win32
{E796E337-DE78-4303-8614-9A590862EE95}.All|Win32.Build.0 = Release|Win32
{E796E337-DE78-4303-8614-9A590862EE95}.All|x64.ActiveCfg = Release|Win32
@ -2040,24 +2030,24 @@ Global
{D1ABE208-6442-4FB4-9AAD-1677E41BC870}.All|x64.Build.0 = Release|Win32
{D1ABE208-6442-4FB4-9AAD-1677E41BC870}.Debug|Win32.ActiveCfg = Debug|Win32
{D1ABE208-6442-4FB4-9AAD-1677E41BC870}.Debug|Win32.Build.0 = Debug|Win32
{D1ABE208-6442-4FB4-9AAD-1677E41BC870}.Debug|x64.ActiveCfg = Debug|Win32
{D1ABE208-6442-4FB4-9AAD-1677E41BC870}.Debug|x64.Build.0 = Debug|Win32
{D1ABE208-6442-4FB4-9AAD-1677E41BC870}.Debug|x64.ActiveCfg = Debug|x64
{D1ABE208-6442-4FB4-9AAD-1677E41BC870}.Debug|x64.Build.0 = Debug|x64
{D1ABE208-6442-4FB4-9AAD-1677E41BC870}.Release|Win32.ActiveCfg = Release|Win32
{D1ABE208-6442-4FB4-9AAD-1677E41BC870}.Release|Win32.Build.0 = Release|Win32
{D1ABE208-6442-4FB4-9AAD-1677E41BC870}.Release|x64.ActiveCfg = Release|Win32
{D1ABE208-6442-4FB4-9AAD-1677E41BC870}.Release|x64.Build.0 = Release|Win32
{D1ABE208-6442-4FB4-9AAD-1677E41BC870}.Release|x64.ActiveCfg = Release|x64
{D1ABE208-6442-4FB4-9AAD-1677E41BC870}.Release|x64.Build.0 = Release|x64
{BA599D0A-4310-4505-91DA-6A6447B3E289}.All|Win32.ActiveCfg = Release|Win32
{BA599D0A-4310-4505-91DA-6A6447B3E289}.All|x64.ActiveCfg = Release|Win32
{BA599D0A-4310-4505-91DA-6A6447B3E289}.Debug|Win32.ActiveCfg = Debug|Win32
{BA599D0A-4310-4505-91DA-6A6447B3E289}.Debug|x64.ActiveCfg = Debug|Win32
{BA599D0A-4310-4505-91DA-6A6447B3E289}.Debug|x64.ActiveCfg = Debug|x64
{BA599D0A-4310-4505-91DA-6A6447B3E289}.Release|Win32.ActiveCfg = Release|Win32
{BA599D0A-4310-4505-91DA-6A6447B3E289}.Release|x64.ActiveCfg = Release|Win32
{BA599D0A-4310-4505-91DA-6A6447B3E289}.Release|x64.ActiveCfg = Release|x64
{EED13FC7-4F81-4E6F-93DB-CDB7DF5CF959}.All|Win32.ActiveCfg = Release|Win32
{EED13FC7-4F81-4E6F-93DB-CDB7DF5CF959}.All|x64.ActiveCfg = Release|Win32
{EED13FC7-4F81-4E6F-93DB-CDB7DF5CF959}.Debug|Win32.ActiveCfg = Debug|Win32
{EED13FC7-4F81-4E6F-93DB-CDB7DF5CF959}.Debug|x64.ActiveCfg = Debug|Win32
{EED13FC7-4F81-4E6F-93DB-CDB7DF5CF959}.Debug|x64.ActiveCfg = Debug|x64
{EED13FC7-4F81-4E6F-93DB-CDB7DF5CF959}.Release|Win32.ActiveCfg = Release|Win32
{EED13FC7-4F81-4E6F-93DB-CDB7DF5CF959}.Release|x64.ActiveCfg = Release|Win32
{EED13FC7-4F81-4E6F-93DB-CDB7DF5CF959}.Release|x64.ActiveCfg = Release|x64
{70564D74-199A-4452-9C60-19ED5F242F0D}.All|Win32.ActiveCfg = Release|x64
{70564D74-199A-4452-9C60-19ED5F242F0D}.All|x64.ActiveCfg = Release|x64
{70564D74-199A-4452-9C60-19ED5F242F0D}.All|x64.Build.0 = Release|x64
@ -2471,6 +2461,7 @@ Global
{36E854E3-CE12-4348-A125-CCF3F9D74813} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{7B077E7F-1BE7-4291-AB86-55E527B25CAC} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{7B42BDA1-72C0-4378-A9B6-5C530F8CD61E} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{834E2B2F-5483-4B80-8FE3-FE48FF76E5C0} = {0C808854-54D1-4230-BFF5-77B5FD905000}
{692F6330-4D87-4C82-81DF-40DB5892636E} = {4CF6A6AC-07DE-4B9E-ABE1-7F98B64E0BB0}
{2286DA73-9FC5-45BC-A508-85994C3317AB} = {4CF6A6AC-07DE-4B9E-ABE1-7F98B64E0BB0}
{66444AEE-554C-11DD-A9F0-8C5D56D89593} = {4CF6A6AC-07DE-4B9E-ABE1-7F98B64E0BB0}

View File

@ -34,6 +34,7 @@ applications/mod_valet_parking
#applications/mod_stress
#applications/mod_snapshot
#applications/mod_snipe_hunt
#applications/mod_callcenter
codecs/mod_g723_1
codecs/mod_amr
#codecs/mod_amrwb

View File

@ -0,0 +1,28 @@
<configuration name="callcenter.conf" description="CallCenter">
<settings>
<!--<param name="odbc-dsn" value="dsn:user:pass"/>-->
</settings>
<queues>
<queue name="support@default">
<param name="strategy" value="longest-idle-agent"/>
<param name="moh-sound" value="$${hold_music}"/>
<!--<param name="record-template" value="$${base_dir}/recordings/${strftime(%Y-%m-%d-%H-%M-%S)}.${destination_number}.${caller_id_number}.${uuid}.wav"/>-->
<param name="time-base-score" value="system"/>
</queue>
</queues>
<!-- WARNING : Configuring XML Agents will updated into the DB upon restart -->
<!-- WARNING : Configuring XML Tiers will reset the provided level and position if provided.-->
<!-- WARNING : Agents and Tiers XML config shouldn't be used in a multi FS shared DB setup(Not currently supported anyway) -->
<agents>
<!--<agent name="1000@default" type="callback" contact="[call_timeout=10]user/1000@default" status="Available" max-no-answer="3" wrap-up-time="10" />-->
</agents>
<tiers>
<!-- if no level or position is provided, they will default to 1. You should do this to keep db value on restart -->
<!-- <tier agent="1000@default" queue="support@default" level="1" position="1"/> -->
</tiers>
</configuration>

View File

@ -79,6 +79,8 @@
<!--<param name="rtp-end-port" value="32768"/>-->
<param name="rtp-enable-zrtp" value="true"/>
<!-- <param name="core-db-dsn" value="dsn:username:password" /> -->
<!-- The system will create all the db schemas automaticly, set this to false to avoid this behaviour-->
<!--<param name="auto-create-schemas" value="true"/>-->
</settings>
</configuration>

View File

@ -145,6 +145,7 @@
<action application="hash" data="insert/${domain_name}-spymap/${caller_id_number}/${uuid}"/>
<action application="hash" data="insert/${domain_name}-last_dial/${caller_id_number}/${destination_number}"/>
<action application="hash" data="insert/${domain_name}-last_dial/global/${uuid}"/>
<action application="set" data="RFC2822_DATE=${strftime(%a, %d %b %Y %T %z)}"/>
</condition>
</extension>
@ -269,7 +270,7 @@
</extension>
<extension name="Local_Extension_Skinny">
<condition field="destination_number" expression="^(20[01][0-9])$">
<condition field="destination_number" expression="^(11[01][0-9])$">
<action application="bridge" data="skinny/internal/${destination_number}"/>
</condition>
</extension>

View File

@ -27,6 +27,7 @@
<extension name="outside_call" continue="true">
<condition>
<action application="set" data="outside_call=true"/>
<action application="set" data="RFC2822_DATE=${strftime(%a, %d %b %Y %T %z)}"/>
</condition>
</extension>

View File

@ -5,7 +5,7 @@
</condition>
</extension>
<extension name="Local_Extension_Skinny">
<condition field="destination_number" expression="^(20[01][0-9])$">
<condition field="destination_number" expression="^(11[01][0-9])$">
<action application="skinny-route"/>
</condition>
</extension>

View File

@ -17,12 +17,12 @@
value is the directory number (or user)
caller-name is shown to the calling party during call
-->
<button position="1" type="Line" label="Line 1" value="2001" caller-name="Calling as 2001"/>
<button position="3" type="Line" label="Shared Line 10" value="2010" caller-name="Calling as 2010"/>
<button position="1" type="Line" label="Line 1" value="1101" caller-name="Calling as 1101"/>
<button position="3" type="Line" label="Shared Line 10" value="1110" caller-name="Calling as 1110"/>
<!--
value is the directory number to call
-->
<button position="5" type="SpeedDial" label="Test" value="2011"/>
<button position="5" type="SpeedDial" label="Call 1001" value="1001"/>
<!--
value is the URL
-->

View File

@ -1,4 +1,5 @@
From: "${voicemail_caller_id_name}" <${voicemail_caller_id_number}@${voicemail_domain}>
Date: ${RFC2822_DATE}
To: <${voicemail_notify_email}>
Subject: Voicemail from "${voicemail_caller_id_name}" <${voicemail_caller_id_number}> ${voicemail_message_len}
X-Priority: ${voicemail_priority}

View File

@ -1,4 +1,5 @@
From: "${voicemail_caller_id_name}" <${voicemail_caller_id_number}@${voicemail_domain}>
Date: ${RFC2822_DATE}
To: <${voicemail_email}>
Subject: Voicemail from "${voicemail_caller_id_name}" <${voicemail_caller_id_number}> ${voicemail_message_len}
X-Priority: ${voicemail_priority}

View File

@ -38,13 +38,19 @@ AC_ARG_WITH([modinstdir],
AC_SUBST(modulesdir)
AC_DEFINE_UNQUOTED([SWITCH_MOD_DIR],"${modulesdir}",[where to install the modules to])
if test "$localstatedir" = "\${prefix}/var" ; then
rundir="$prefix/run"
logfiledir="${prefix}/log"
else
rundir="$localstatedir/run/freeswitch"
logfiledir="$localstatedir/log/freeswitch"
fi
# Where to put pidfile
AC_ARG_WITH([rundir],
[AS_HELP_STRING([--with-rundir=DIR], [Put pidfile into this location (default: $prefix/run)])], [runtimedir="$withval"], [runtimedir="${prefix}/run"])
[AS_HELP_STRING([--with-rundir=DIR], [Put pidfile into this location (default: $prefix/run)])], [runtimedir="$withval"], [runtimedir="$rundir"])
AC_SUBST(runtimedir)
AC_DEFINE_UNQUOTED([SWITCH_RUN_DIR],"${runtimedir}",[where to put pidfile to])
logfiledir="${prefix}/log"
AC_SUBST(logfiledir)
AC_DEFINE_UNQUOTED([SWITCH_LOG_DIR],"${logfiledir}",[where to put log files])
@ -725,6 +731,10 @@ AC_ARG_WITH(libcurl,
AC_HELP_STRING([--with-libcurl=DIR],[look for the curl library in DIR]),
[_libcurl_with=$withval],[_libcurl_with=ifelse([$1],,[yes],[$1])])
AC_CACHE_CHECK([whether to use system libcurl library], [ac_cv_use_system_curl], [
LIBCURL_CHECK_CONFIG([yes], [7.13.0], [ac_cv_use_system_curl='yes'], [ac_cv_use_system_curl='no'])
])
if test "$_libcurl_with" = "no" ; then
ac_cv_use_system_curl=no;
fi
@ -732,10 +742,6 @@ if test "$_libcurl_with" = "yes" ; then
ac_cv_use_system_curl=yes;
fi
AC_CACHE_CHECK([whether to use system libcurl library], [ac_cv_use_system_curl], [
LIBCURL_CHECK_CONFIG([yes], [7.13.0], [ac_cv_use_system_curl='yes'], [ac_cv_use_system_curl='no'])
])
if test "$ac_cv_use_system_curl" != "yes" ; then
LIBCURL_DEPS='${switch_builddir}/libs/curl/lib/libcurl.la'
LIBCURL='${switch_builddir}/libs/curl/lib/libcurl.la'

View File

@ -35,6 +35,8 @@
%define prefix %{_prefix}
%define sysconfdir /opt/freeswitch/conf
%define _sysconfdir %{sysconfdir}
%define logfiledir /var/log/freeswitch
%define runtimedir /var/run/freeswitch
Name: freeswitch
Summary: FreeSWITCH open source telephony platform
@ -320,7 +322,7 @@ export QA_RPATHS=$[ 0x0001|0x0002 ]
# Application Modules
#
###############################################################################################################################
APPLICATION_MODULES_AE="applications/mod_avmd applications/mod_commands applications/mod_conference applications/mod_db applications/mod_directory applications/mod_distributor applications/mod_dptools applications/mod_easyroute applications/mod_enum applications/mod_esf applications/mod_expr"
APPLICATION_MODULES_AE="applications/mod_avmd applications/mod_commands applications/mod_conference applications/mod_db applications/mod_directory applications/mod_distributor applications/mod_dptools applications/mod_easyroute applications/mod_enum applications/mod_esf applications/mod_expr applications/mod_callcenter"
APPLICATION_MODULES_FM="applications/mod_fifo applications/mod_fsv applications/mod_hash applications/mod_lcr applications/mod_limit applications/mod_memcache"
@ -425,7 +427,7 @@ test ! -f modules.conf || rm -f modules.conf
touch modules.conf
for i in $MODULES; do echo $i >> modules.conf; done
export VERBOSE=yes
export DESTDIR=$RPM_BUILD_ROOT/
export DESTDIR=%{buildroot}/
export PKG_CONFIG_PATH=/usr/bin/pkg-config:$PKG_CONFIG_PATH
export ACLOCAL_FLAGS="-I /usr/share/aclocal"
@ -472,29 +474,31 @@ touch .noversion
###############################################################################################################################
%install
%{__make} DESTDIR=$RPM_BUILD_ROOT install
%{__make} DESTDIR=%{buildroot} install
# Create a log dir
%{__mkdir} -p $RPM_BUILD_ROOT%{prefix}/log
%{__mkdir} -p %{buildroot}%{prefix}/log
%{__mkdir} -p %{buildroot}%{logfiledir}
%{__mkdir} -p %{buildroot}%{runtimedir}
%ifos linux
# Install init files
# On SuSE:
%if 0%{?suse_version} > 100
%{__install} -D -m 744 build/freeswitch.init.suse $RPM_BUILD_ROOT/etc/init.d/freeswitch
%{__install} -D -m 744 build/freeswitch.init.suse %{buildroot}/etc/rc.d/init.d/freeswitch
%else
# On RedHat like
%{__install} -D -m 0755 build/freeswitch.init.redhat $RPM_BUILD_ROOT/etc/init.d/freeswitch
%{__install} -D -m 0755 build/freeswitch.init.redhat %{buildroot}/etc/rc.d/init.d/freeswitch
%endif
# On SuSE make /usr/sbin/rcfreeswitch a link to /etc/init.d/freeswitch
# On SuSE make /usr/sbin/rcfreeswitch a link to /etc/rc.d/init.d/freeswitch
%if 0%{?suse_version} > 100
%{__mkdir} -p $RPM_BUILD_ROOT/usr/sbin
%{__ln_s} -f /etc/init.d/freeswitch $RPM_BUILD_ROOT/usr/sbin/rcfreeswitch
%{__mkdir} -p %{buildroot}/usr/sbin
%{__ln_s} -f /etc/rc.d/init.d/freeswitch %{buildroot}/usr/sbin/rcfreeswitch
%endif
# Add the sysconfiguration file
%{__install} -D -m 744 build/freeswitch.sysconfig $RPM_BUILD_ROOT/etc/sysconfig/freeswitch
%{__install} -D -m 744 build/freeswitch.sysconfig %{buildroot}/etc/sysconfig/freeswitch
# Add monit file
%{__install} -D -m 644 build/freeswitch.monitrc $RPM_BUILD_ROOT/etc/monit.d/freeswitch.monitrc
%{__install} -D -m 644 build/freeswitch.monitrc %{buildroot}/etc/monit.d/freeswitch.monitrc
%endif
@ -533,7 +537,7 @@ if [ $1 -eq 0 ]; then
fi
%clean
%{__rm} -rf $RPM_BUILD_ROOT
%{__rm} -rf %{buildroot}
%files
###############################################################################################################################
@ -554,9 +558,8 @@ fi
%dir %attr(0750, freeswitch, daemon) %{prefix}/db
%dir %attr(0750, freeswitch, daemon) %{prefix}/grammar
%dir %attr(0750, freeswitch, daemon) %{prefix}/htdocs
%dir %attr(0750, freeswitch, daemon) %{prefix}/log
%dir %attr(0750, freeswitch, daemon) %{prefix}/log/xml_cdr
%dir %attr(0750, freeswitch, daemon) %{prefix}/run
%dir %attr(0750, freeswitch, daemon) %{logfiledir}
%dir %attr(0750, freeswitch, daemon) %{runtimedir}
%dir %attr(0750, freeswitch, daemon) %{prefix}/scripts
#
#################################### Config Directory Structure ################################################################
@ -597,6 +600,7 @@ fi
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/mime.types
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/acl.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/alsa.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/callcenter.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_csv.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cdr_pg_csv.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/cidlookup.conf.xml
@ -700,7 +704,7 @@ fi
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/htdocs/*
%ifos linux
#/etc/ld.so.conf.d/*
/etc/init.d/freeswitch
/etc/rc.d/init.d/freeswitch
/etc/sysconfig/freeswitch
%if 0%{?suse_version} > 100
/usr/sbin/rcfreeswitch
@ -743,6 +747,7 @@ fi
%{prefix}/mod/mod_event_multicast.so*
%{prefix}/mod/mod_event_socket.so*
%{prefix}/mod/mod_expr.so*
%{prefix}/mod/mod_callcenter.so*
%{prefix}/mod/mod_fifo.so*
%{prefix}/mod/mod_file_string.so*
%{prefix}/mod/mod_flite.so*
@ -810,11 +815,7 @@ fi
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/zt.conf
%{prefix}/lib/libopenzap.so*
%{prefix}/mod/mod_openzap.so*
%{prefix}/mod/ozmod_analog.so*
%{prefix}/mod/ozmod_analog_em.so*
%{prefix}/mod/ozmod_isdn.so*
%{prefix}/mod/ozmod_skel.so*
%{prefix}/mod/ozmod_zt.so*
%{prefix}/mod/ozmod_*.so*
###############################################################################################################################
#

View File

@ -566,6 +566,8 @@ static int usage(char *name){
printf(" -x, --execute=command Execute Command and Exit\n");
printf(" -l, --loglevel=command Log Level\n");
printf(" -q, --quiet Disable logging\n");
printf(" -r, --retry Retry connection on failure\n");
printf(" -R, --reconnect Reconnect if disconnected\n");
printf(" -d, --debug=level Debug Level (0 - 7)\n\n");
return 1;
}
@ -581,7 +583,7 @@ static void *msg_thread_run(esl_thread_t *me, void *obj)
esl_status_t status = esl_recv_event_timed(handle, 10, 1, NULL);
if (status == ESL_FAIL) {
esl_log(ESL_LOG_WARNING, "Disconnected.\n");
running = thread_running = 0;
running = -1; thread_running = 0;
} else if (status == ESL_SUCCESS) {
if (handle->last_event) {
const char *type = esl_event_get_header(handle->last_event, "content-type");
@ -613,7 +615,7 @@ static void *msg_thread_run(esl_thread_t *me, void *obj)
}
known++;
} else if (!strcasecmp(type, "text/disconnect-notice")) {
running = thread_running = 0;
running = -1; thread_running = 0;
known++;
} else if (!strcasecmp(type, "text/event-plain")) {
char *foo;
@ -718,7 +720,7 @@ static int process_command(esl_handle_t *handle, const char *cmd)
snprintf(cmd_str, sizeof(cmd_str), "api %s\nconsole_execute: true\n\n", cmd);
if (esl_send_recv(handle, cmd_str)) {
printf("Socket interrupted, bye!\n");
return 1;
return -1;
}
if (handle->last_sr_event) {
if (handle->last_sr_event->body) {
@ -987,6 +989,8 @@ int main(int argc, char *argv[])
{"execute", 1, 0, 'x'},
{"loglevel", 1, 0, 'l'},
{"quiet", 0, 0, 'q'},
{"retry", 0, 0, 'r'},
{"reconnect", 0, 0, 'R'},
{0, 0, 0, 0}
};
@ -1004,7 +1008,7 @@ int main(int argc, char *argv[])
char argv_command[256] = "";
char argv_loglevel[128] = "";
int argv_quiet = 0;
int loops = 2;
int loops = 2, reconnect = 0;
strncpy(internal_profile.host, "127.0.0.1", sizeof(internal_profile.host));
strncpy(internal_profile.pass, "ClueCon", sizeof(internal_profile.pass));
@ -1026,7 +1030,7 @@ int main(int argc, char *argv[])
for(;;) {
int option_index = 0;
opt = getopt_long(argc, argv, "H:U:P:S:u:p:d:x:l:qrh?", options, &option_index);
opt = getopt_long(argc, argv, "H:U:P:S:u:p:d:x:l:qrRh?", options, &option_index);
if (opt == -1) break;
switch (opt)
{
@ -1073,6 +1077,9 @@ int main(int argc, char *argv[])
case 'r':
loops += 120;
break;
case 'R':
reconnect = 1;
break;
case 'h':
case '?':
print_banner(stdout);
@ -1190,6 +1197,8 @@ int main(int argc, char *argv[])
snprintf(prompt_str, sizeof(prompt_str), "freeswitch@%s> ", profile->name);
}
connect:
while (--loops > 0) {
memset(&handle, 0, sizeof(handle));
if (esl_connect(&handle, profile->host, profile->port, profile->user, profile->pass)) {
@ -1314,8 +1323,9 @@ int main(int argc, char *argv[])
esl_log(ESL_LOG_INFO, "FS CLI Ready.\nenter /help for a list of commands.\n");
printf("%s\n", handle.last_sr_reply);
while (running) {
while (running > 0) {
int r;
#ifdef HAVE_EDITLINE
line = el_gets(el, &count);
#else
@ -1341,8 +1351,8 @@ int main(int argc, char *argv[])
history(myhistory, &ev, H_ENTER, line);
#endif
if (process_command(&handle, cmd)) {
running = 0;
if ((r = process_command(&handle, cmd))) {
running = r;
}
#ifdef HAVE_EDITLINE
@ -1357,6 +1367,13 @@ int main(int argc, char *argv[])
}
if (running < 0 && reconnect) {
running = 1;
loops = 120;
goto connect;
}
#ifdef HAVE_EDITLINE
done:
history(myhistory, &ev, H_SAVE, hfile);

View File

@ -34,6 +34,7 @@
#include <esl.h>
#ifndef WIN32
#define closesocket(x) close(x)
#include <fcntl.h>
#else
#include <Ws2tcpip.h>
#endif
@ -606,13 +607,15 @@ ESL_DECLARE(esl_status_t) esl_listen(const char *host, esl_port_t port, esl_list
}
ESL_DECLARE(esl_status_t) esl_connect(esl_handle_t *handle, const char *host, esl_port_t port, const char *user, const char *password)
ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *host, esl_port_t port, const char *user, const char *password, uint32_t timeout)
{
char sendbuf[256];
int rval = 0;
const char *hval;
struct addrinfo hints = { 0 }, *result;
#ifdef WIN32
#ifndef WIN32
int fd_flags;
#else
WORD wVersionRequested = MAKEWORD(2, 0);
WSADATA wsaData;
int err = WSAStartup(wVersionRequested, &wsaData);
@ -643,13 +646,72 @@ ESL_DECLARE(esl_status_t) esl_connect(esl_handle_t *handle, const char *host, es
goto fail;
}
memcpy(&handle->sockaddr, result->ai_addr, result->ai_addrlen);
memcpy(&handle->sockaddr, result->ai_addr, sizeof(handle->sockaddr));
handle->sockaddr.sin_family = AF_INET;
handle->sockaddr.sin_port = htons(port);
freeaddrinfo(result);
if (timeout) {
#ifdef WIN32
u_long arg = 1;
if (ioctlsocket(handle->sock, FIONBIO, &arg) == SOCKET_ERROR) {
snprintf(handle->err, sizeof(handle->err), "Socket Connection Error");
goto fail;
}
#else
fd_flags = fcntl(handle->sock, F_GETFL, 0);
if (fcntl(handle->sock, F_SETFL, fd_flags | O_NONBLOCK)) {
snprintf(handle->err, sizeof(handle->err), "Socket Connection Error");
goto fail;
}
#endif
}
rval = connect(handle->sock, (struct sockaddr*)&handle->sockaddr, sizeof(handle->sockaddr));
freeaddrinfo(result);
if (timeout) {
fd_set wfds;
struct timeval tv;
int r;
tv.tv_sec = timeout / 1000;
tv.tv_usec = (timeout % 1000) * 1000;
FD_ZERO(&wfds);
#ifdef WIN32
#pragma warning( push )
#pragma warning( disable : 4127 )
FD_SET(handle->sock, &wfds);
#pragma warning( pop )
#else
FD_SET(handle->sock, &wfds);
#endif
r = select(handle->sock + 1, NULL, &wfds, NULL, &tv);
if (r <= 0) {
snprintf(handle->err, sizeof(handle->err), "Connection timed out");
goto fail;
}
if (!FD_ISSET(handle->sock, &wfds)) {
snprintf(handle->err, sizeof(handle->err), "Connection timed out");
goto fail;
}
#ifdef WIN32
{
u_long arg = 0;
if (ioctlsocket(handle->sock, FIONBIO, &arg) == SOCKET_ERROR) {
snprintf(handle->err, sizeof(handle->err), "Socket Connection Error");
goto fail;
}
}
#else
fcntl(handle->sock, F_SETFL, fd_flags);
#endif
rval = 0;
}
result = NULL;
if (rval) {
@ -661,7 +723,7 @@ ESL_DECLARE(esl_status_t) esl_connect(esl_handle_t *handle, const char *host, es
handle->connected = 1;
if (esl_recv(handle)) {
if (esl_recv_timed(handle, timeout)) {
snprintf(handle->err, sizeof(handle->err), "Connection Error");
goto fail;
}
@ -682,7 +744,7 @@ ESL_DECLARE(esl_status_t) esl_connect(esl_handle_t *handle, const char *host, es
esl_send(handle, sendbuf);
if (esl_recv(handle)) {
if (esl_recv_timed(handle, timeout)) {
snprintf(handle->err, sizeof(handle->err), "Authentication Error");
goto fail;
}
@ -748,6 +810,10 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms
struct timeval tv = { 0 };
int max, activity;
esl_status_t status = ESL_SUCCESS;
if (!ms) {
return esl_recv_event(handle, check_q, save_event);
}
if (!handle || !handle->connected || handle->sock == ESL_SOCK_INVALID) {
return ESL_FAIL;
@ -764,7 +830,6 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms
tv.tv_usec = ms * 1000;
FD_ZERO(&rfds);
FD_ZERO(&efds);
@ -1090,7 +1155,7 @@ ESL_DECLARE(esl_status_t) esl_send(esl_handle_t *handle, const char *cmd)
}
ESL_DECLARE(esl_status_t) esl_send_recv(esl_handle_t *handle, const char *cmd)
ESL_DECLARE(esl_status_t) esl_send_recv_timed(esl_handle_t *handle, const char *cmd, uint32_t ms)
{
const char *hval;
esl_status_t status;
@ -1120,7 +1185,7 @@ ESL_DECLARE(esl_status_t) esl_send_recv(esl_handle_t *handle, const char *cmd)
recv:
status = esl_recv_event(handle, 0, &handle->last_sr_event);
status = esl_recv_event_timed(handle, ms, 0, &handle->last_sr_event);
if (handle->last_sr_event) {
char *ct = esl_event_get_header(handle->last_sr_event,"content-type");

View File

@ -351,6 +351,10 @@ const char *ESLevent::serialize(const char *format)
esl_safe_free(serialized_string);
if (format == NULL) {
format = "text";
}
if (!event) {
return "";
}

View File

@ -387,8 +387,11 @@ ESL_DECLARE(esl_status_t) esl_sendevent(esl_handle_t *handle, esl_event_t *event
\param port Port to be connected
\param password FreeSWITCH server username (optional)
\param password FreeSWITCH server password
\param timeout Connection timeout, in miliseconds
*/
ESL_DECLARE(esl_status_t) esl_connect(esl_handle_t *handle, const char *host, esl_port_t port, const char *user, const char *password);
ESL_DECLARE(esl_status_t) esl_connect_timeout(esl_handle_t *handle, const char *host, esl_port_t port, const char *user, const char *password, uint32_t timeout);
#define esl_connect(_handle, _host, _port, _user, _password) esl_connect_timeout(_handle, _host, _port, _user, _password, 0)
/*!
\brief Disconnect a handle
\param handle Handle to be disconnected
@ -420,7 +423,8 @@ ESL_DECLARE(esl_status_t) esl_recv_event_timed(esl_handle_t *handle, uint32_t ms
\param handle Handle to be used
\param cmd Raw command to send
*/
ESL_DECLARE(esl_status_t) esl_send_recv(esl_handle_t *handle, const char *cmd);
ESL_DECLARE(esl_status_t) esl_send_recv_timed(esl_handle_t *handle, const char *cmd, uint32_t ms);
#define esl_send_recv(_handle, _cmd) esl_send_recv_timed(_handle, _cmd, 0)
/*!
\brief Applies a filter to received events
\param handle Handle to apply the filter to

View File

@ -41,11 +41,16 @@ INCS += -I$(FT_SRCDIR)/$(SRC)/ftmod/ftmod_sangoma_boost
if SNGSS7
INCS += -I/usr/include/sng_ss7/
endif
MY_CFLAGS = $(INCS) $(FTDM_CFLAGS) -DFTDM_CONFIG_DIR=\"@confdir@\" -DFTDM_MOD_DIR=\"$(moddir)\" @COMP_VENDOR_CFLAGS@ @DEFS@
COMPILE = $(CC) $(MY_CFLAGS) $(INCS)
LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(COMPILE)
LINK = $(LIBTOOL) --mode=link --tag=CC $(CC) $(MY_CFLAGS) $(LDFLAGS) -o $@
if DEBUGDTMF
MY_CFLAGS += -DFTDM_DEBUG_DTMF
endif
#
# GNU pkgconfig file
@ -167,10 +172,18 @@ if LIBPRI
mod_LTLIBRARIES += ftmod_libpri.la
endif
if PRITAP
mod_LTLIBRARIES += ftmod_pritap.la
endif
if SNGSS7
mod_LTLIBRARIES += ftmod_sangoma_ss7.la
endif
if SNGISDN
mod_LTLIBRARIES += ftmod_sangoma_isdn.la
endif
if OPENR2
mod_LTLIBRARIES += ftmod_r2.la
endif
@ -243,6 +256,13 @@ ftmod_libpri_la_LDFLAGS = -module -avoid-version -lpri
ftmod_libpri_la_LIBADD = $(MYLIB)
endif
if PRITAP
ftmod_pritap_la_SOURCES = $(SRC)/ftmod/ftmod_pritap/ftmod_pritap.c
ftmod_pritap_la_CFLAGS = $(AM_CFLAGS) $(MY_CFLAGS)
ftmod_pritap_la_LDFLAGS = -module -avoid-version -lpri
ftmod_pritap_la_LIBADD = $(MYLIB)
endif
if SNGSS7
ftmod_sangoma_ss7_la_SOURCES = $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c \
$(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c \

View File

@ -165,11 +165,25 @@ AC_ARG_WITH([libpri],
[AS_HELP_STRING([--with-libpri], [Install ftmod_libpri])], [enable_libpri="yes"], [enable_libpri="no"])
AC_SUBST(enable_libpri)
# pritap?
AC_ARG_WITH([pritap],
[AS_HELP_STRING([--with-pritap], [Install ftmod_pritap])], [enable_pritap="yes"], [enable_pritap="no"])
AC_SUBST(enable_pritap)
# debug dtmf?
AC_ARG_WITH([debugdtmf],
[AS_HELP_STRING([--with-debugdtmf], [Debug DTMF])], [enable_debugdtmf="yes"], [enable_debugdtmf="no"])
AC_SUBST(enable_debugdtmf)
AC_CHECK_LIB([sangoma], [sangoma_span_chan_toif], [have_libsangoma="yes"])
AM_CONDITIONAL([LIBSANGOMA],[test "${have_libsangoma}" = "yes"])
AM_CONDITIONAL([LIBPRI],[test "${enable_libpri}" = "yes"])
AM_CONDITIONAL([PRITAP],[test "${enable_pritap}" = "yes"])
AM_CONDITIONAL([DEBUGDTMF],[test "${enable_debugdtmf}" = "yes"])
AC_CHECK_LIB([sng_ss7], [sng_isup_init], [have_sng_ss7="yes"])
AM_CONDITIONAL([SNGSS7],[test "${have_sng_ss7}" = "yes"])

View File

@ -38,6 +38,7 @@
#define __FUNCTION__ __SWITCH_FUNC__
#endif
#define FREETDM_LIMIT_REALM "__freetdm"
#define FREETDM_VAR_PREFIX "freetdm_"
#define FREETDM_VAR_PREFIX_LEN 8
@ -55,6 +56,11 @@ typedef enum {
ANALOG_OPTION_CALL_SWAP = (1 << 1)
} analog_option_t;
typedef enum {
FTDM_LIMIT_RESET_ON_TIMEOUT = 0,
FTDM_LIMIT_RESET_ON_ANSWER = 1
} limit_reset_event_t;
typedef enum {
TFLAG_IO = (1 << 0),
TFLAG_DTMF = (1 << 1),
@ -119,6 +125,10 @@ struct span_config {
char hold_music[256];
char type[256];
analog_option_t analog_options;
const char *limit_backend;
int limit_calls;
int limit_seconds;
limit_reset_event_t limit_reset_event;
chan_pvt_t pvts[FTDM_MAX_CHANNELS_SPAN];
};
@ -1211,7 +1221,21 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
caller_data.pres = (uint8_t)atoi(sipvar);
}
}
if (session) {
/* take out some other values from the session if they're present */
switch_channel_t *channel = switch_core_session_get_channel(session);
const char *freetdmvar;
freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_capability");
if (freetdmvar) {
caller_data.bearer_capability = (uint8_t)atoi(freetdmvar);
}
freetdmvar = switch_channel_get_variable(channel, "freetdm_bearer_layer1");
if (freetdmvar) {
caller_data.bearer_layer1 = (uint8_t)atoi(freetdmvar);
}
}
if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) {
caller_data.screen = 1;
}
@ -1292,6 +1316,9 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
switch_caller_profile_t *caller_profile;
switch_channel_t *channel = switch_core_session_get_channel(*new_session);
span_id = ftdm_channel_get_span_id(ftdmchan);
chan_id = ftdm_channel_get_id(ftdmchan);
switch_core_session_add_stream(*new_session, NULL);
if ((tech_pvt = (private_t *) switch_core_session_alloc(*new_session, sizeof(private_t))) != 0) {
tech_init(tech_pvt, *new_session, ftdmchan);
@ -1302,12 +1329,12 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
goto fail;
}
snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", ftdm_channel_get_span_id(ftdmchan), ftdm_channel_get_id(ftdmchan), dest);
snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", span_id, chan_id, dest);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name);
switch_channel_set_name(channel, name);
switch_channel_set_variable(channel, "freetdm_span_name", ftdm_channel_get_span_name(ftdmchan));
switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", ftdm_channel_get_span_id(ftdmchan));
switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", ftdm_channel_get_id(ftdmchan));
switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", span_id);
switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chan_id);
ftdm_channel_set_caller_data(ftdmchan, &caller_data);
caller_profile = switch_caller_profile_clone(*new_session, outbound_profile);
caller_profile->destination_number = switch_core_strdup(caller_profile->pool, switch_str_nil(dest_num));
@ -1325,6 +1352,18 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
}
if (SPAN_CONFIG[span_id].limit_calls) {
char spanresource[512];
snprintf(spanresource, sizeof(spanresource), "span_%s_%s", ftdm_channel_get_span_name(ftdmchan), caller_data.dnis.digits);
ftdm_log(FTDM_LOG_DEBUG, "Adding rate limit resource on channel %d:%d (%s/%s/%d/%d)\n", span_id, chan_id, FREETDM_LIMIT_REALM,
spanresource, SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds);
if (switch_limit_incr("hash", *new_session, FREETDM_LIMIT_REALM, spanresource, SPAN_CONFIG[span_id].limit_calls, SPAN_CONFIG[span_id].limit_seconds) != SWITCH_STATUS_SUCCESS) {
switch_core_session_destroy(new_session);
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
goto fail;
}
}
if ((status = ftdm_channel_call_place(ftdmchan)) != FTDM_SUCCESS) {
if (tech_pvt->read_codec.implementation) {
switch_core_codec_destroy(&tech_pvt->read_codec);
@ -1442,6 +1481,8 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
switch_channel_set_variable(channel, "freetdm_span_name", ftdm_channel_get_span_name(sigmsg->channel));
switch_channel_set_variable_printf(channel, "freetdm_span_number", "%d", spanid);
switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chanid);
switch_channel_set_variable_printf(channel, "freetdm_bearer_capability", "%d", channel_caller_data->bearer_capability);
switch_channel_set_variable_printf(channel, "freetdm_bearer_layer1", "%d", channel_caller_data->bearer_layer1);
if (globals.sip_headers) {
switch_channel_set_variable(channel, "sip_h_X-FreeTDM-SpanName", ftdm_channel_get_span_name(sigmsg->channel));
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-SpanNumber", "%d", spanid);
@ -1516,6 +1557,18 @@ static FIO_SIGNAL_CB_FUNCTION(on_common_signal)
}
}
break;
case FTDM_SIGEVENT_UP:
{
/* clear any rate limit resource for this span */
char spanresource[512];
if (SPAN_CONFIG[spanid].limit_reset_event == FTDM_LIMIT_RESET_ON_ANSWER && SPAN_CONFIG[spanid].limit_calls) {
ftdm_caller_data_t *caller_data = ftdm_channel_get_caller_data(sigmsg->channel);
snprintf(spanresource, sizeof(spanresource), "span_%s_%s", ftdm_channel_get_span_name(sigmsg->channel), caller_data->dnis.digits);
ftdm_log(FTDM_LOG_DEBUG, "Clearing rate limit resource on channel %d:%d (%s/%s)\n", spanid, chanid, FREETDM_LIMIT_REALM, spanresource);
switch_limit_interval_reset("hash", FREETDM_LIMIT_REALM, spanresource);
}
return FTDM_SUCCESS;
}
default:
return FTDM_SUCCESS;
break;
@ -2344,7 +2397,7 @@ static switch_status_t load_config(void)
}
}
if ((spans = switch_xml_child(cfg, "sangoma_isdn_spans"))) {
if ((spans = switch_xml_child(cfg, "sangoma_pri_spans")) || (spans = switch_xml_child(cfg, "sangoma_bri_spans"))) {
for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
ftdm_status_t zstatus = FTDM_FAIL;
const char *context = "default";
@ -2362,11 +2415,6 @@ static switch_status_t load_config(void)
continue;
}
if (!configname) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sangoma isdn span missing required attribute, skipping ...\n");
continue;
}
if (name) {
zstatus = ftdm_span_find_by_name(name, &span);
} else {
@ -2399,6 +2447,10 @@ static switch_status_t load_config(void)
}
}
/* some defaults first */
SPAN_CONFIG[span_id].limit_backend = "hash";
SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT;
for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
@ -2412,6 +2464,28 @@ static switch_status_t load_config(void)
context = val;
} else if (!strcasecmp(var, "dialplan")) {
dialplan = val;
} else if (!strcasecmp(var, "call_limit_backend")) {
SPAN_CONFIG[span_id].limit_backend = val;
ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id);
} else if (!strcasecmp(var, "call_limit_rate")) {
int calls;
int seconds;
if (sscanf(val, "%d/%d", &calls, &seconds) != 2) {
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter, format example: 3/1 for 3 calls per second\n", var);
} else {
if (calls < 1 || seconds < 1) {
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, minimum call limit must be 1 per second\n", var);
} else {
SPAN_CONFIG[span_id].limit_calls = calls;
SPAN_CONFIG[span_id].limit_seconds = seconds;
}
}
} else if (!strcasecmp(var, "call_limit_reset_event")) {
if (!strcasecmp(val, "answer")) {
SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_ANSWER;
} else {
ftdm_log(FTDM_LOG_ERROR, "Invalid %s parameter value, only accepted event is 'answer'\n", var);
}
} else {
spanparameters[paramindex].var = var;
spanparameters[paramindex].val = val;
@ -2880,6 +2954,59 @@ static switch_status_t load_config(void)
}
}
if ((spans = switch_xml_child(cfg, "pritap_spans"))) {
for (myspan = switch_xml_child(spans, "span"); myspan; myspan = myspan->next) {
char *name = (char *) switch_xml_attr(myspan, "name");
ftdm_status_t zstatus = FTDM_FAIL;
unsigned paramindex = 0;
ftdm_conf_parameter_t spanparameters[10];
const char *context = "default";
const char *dialplan = "XML";
ftdm_span_t *span = NULL;
int span_id = 0;
if (!name) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "span missing required attribute 'name'\n");
continue;
}
for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
if (!strcasecmp(var, "context")) {
context = val;
} else if (!strcasecmp(var, "dialplan")) {
dialplan = val;
} else {
spanparameters[paramindex].var = var;
spanparameters[paramindex].val = val;
paramindex++;
}
}
zstatus = ftdm_span_find_by_name(name, &span);
if (zstatus != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Error finding FreeTDM span %s\n", name);
continue;
}
span_id = ftdm_span_get_id(span);
if (ftdm_configure_span_signaling(span, "pritap", on_clear_channel_signal, spanparameters) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Error configuring FreeTDM span %s\n", name);
continue;
}
SPAN_CONFIG[span_id].span = span;
switch_copy_string(SPAN_CONFIG[span_id].context, context, sizeof(SPAN_CONFIG[span_id].context));
switch_copy_string(SPAN_CONFIG[span_id].dialplan, dialplan, sizeof(SPAN_CONFIG[span_id].dialplan));
switch_copy_string(SPAN_CONFIG[span_id].type, "isdn", sizeof(SPAN_CONFIG[span_id].type));
ftdm_span_start(span);
}
}
if ((spans = switch_xml_child(cfg, "libpri_spans"))) {

View File

@ -274,7 +274,7 @@ FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_
/* Unsupported */
FT_DECLARE(ftdm_status_t) ftdm_cpu_get_system_idle_time(struct ftdm_cpu_monitor_stats *p, double *idle_percentage)
{
*idle_percentate = 100.0;
*idle_percentage = 100.0;
return FTDM_FAIL;
}
#endif

View File

@ -372,6 +372,10 @@ static ftdm_status_t ftdm_channel_destroy(ftdm_channel_t *ftdmchan)
ftdm_sleep(500);
}
#ifdef FTDM_DEBUG_DTMF
ftdm_mutex_destroy(&ftdmchan->dtmfdbg.mutex);
#endif
ftdm_mutex_lock(ftdmchan->pre_buffer_mutex);
ftdm_buffer_destroy(&ftdmchan->pre_buffer);
ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex);
@ -771,6 +775,9 @@ FT_DECLARE(ftdm_status_t) ftdm_span_add_channel(ftdm_span_t *span, ftdm_socket_t
ftdm_mutex_create(&new_chan->mutex);
ftdm_mutex_create(&new_chan->pre_buffer_mutex);
#ifdef FTDM_DEBUG_DTMF
ftdm_mutex_create(&new_chan->dtmfdbg.mutex);
#endif
ftdm_buffer_create(&new_chan->digit_buffer, 128, 128, 0);
ftdm_buffer_create(&new_chan->gen_dtmf_buffer, 128, 128, 0);
@ -1327,21 +1334,28 @@ static __inline__ int chan_is_avail(ftdm_channel_t *check)
ftdm_test_flag(check, FTDM_CHANNEL_INUSE) ||
ftdm_test_flag(check, FTDM_CHANNEL_SUSPENDED) ||
ftdm_test_flag(check, FTDM_CHANNEL_IN_ALARM) ||
check->state != FTDM_CHANNEL_STATE_DOWN ||
!FTDM_IS_VOICE_CHANNEL(check)) {
check->state != FTDM_CHANNEL_STATE_DOWN) {
return 0;
}
return 1;
}
static __inline__ int request_channel(ftdm_channel_t *check, ftdm_channel_t **ftdmchan,
static __inline__ int chan_voice_is_avail(ftdm_channel_t *check)
{
if (!FTDM_IS_VOICE_CHANNEL(check)) {
return 0;
}
return chan_is_avail(check);
}
static __inline__ int request_voice_channel(ftdm_channel_t *check, ftdm_channel_t **ftdmchan,
ftdm_caller_data_t *caller_data, ftdm_direction_t direction)
{
ftdm_status_t status;
if (chan_is_avail(check)) {
if (chan_voice_is_avail(check)) {
/* unlocked testing passed, try again with the channel locked */
ftdm_mutex_lock(check->mutex);
if (chan_is_avail(check)) {
if (chan_voice_is_avail(check)) {
if (check->span && check->span->channel_request) {
/* I am only unlocking here cuz this function is called
* sometimes with the group or span lock held and were
@ -1461,7 +1475,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_group(uint32_t group_id, ftdm_dir
break;
}
if (request_channel(check, ftdmchan, caller_data, direction)) {
if (request_voice_channel(check, ftdmchan, caller_data, direction)) {
status = FTDM_SUCCESS;
break;
}
@ -1572,7 +1586,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_open_by_span(uint32_t span_id, ftdm_direc
break;
}
if (request_channel(check, ftdmchan, caller_data, direction)) {
if (request_voice_channel(check, ftdmchan, caller_data, direction)) {
status = FTDM_SUCCESS;
break;
}
@ -1899,15 +1913,21 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_unhold(const char *file, const char
FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char *func, int line, ftdm_channel_t *ftdmchan)
{
ftdm_status_t status = FTDM_SUCCESS;
ftdm_channel_lock(ftdmchan);
if (ftdmchan->state == FTDM_CHANNEL_STATE_TERMINATING) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Ignoring answer because the call is already terminating\n");
goto done;
}
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_ANSWERED);
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_MEDIA);
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OUTBOUND)) {
ftdm_channel_unlock(ftdmchan);
return FTDM_SUCCESS;
goto done;
}
if (ftdmchan->state < FTDM_CHANNEL_STATE_PROGRESS) {
@ -1920,14 +1940,33 @@ FT_DECLARE(ftdm_status_t) _ftdm_channel_call_answer(const char *file, const char
ftdm_channel_set_state(file, func, line, ftdmchan, FTDM_CHANNEL_STATE_UP, 1);
done:
ftdm_channel_unlock(ftdmchan);
return FTDM_SUCCESS;
return status;
}
/* lock must be acquired by the caller! */
static ftdm_status_t call_hangup(ftdm_channel_t *chan, const char *file, const char *func, int line)
{
if (chan->state != FTDM_CHANNEL_STATE_DOWN) {
if (chan->state == FTDM_CHANNEL_STATE_HANGUP) {
/* make user's life easier, and just ignore double hangup requests */
return FTDM_SUCCESS;
}
if (chan->state == FTDM_CHANNEL_STATE_TERMINATING && ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) {
/* the signaling stack is already terminating the call but has not yet notified the user about it
* with SIGEVENT_STOP, we must flag this channel as hangup and wait for the SIGEVENT_STOP before
* proceeding, at that point we will move the channel to hangup, but the SIGEVENT_STOP will not
* be sent to the user since they already made clear they want to hangup!
* */
ftdm_set_flag(chan, FTDM_CHANNEL_USER_HANGUP);
ftdm_wait_for_flag_cleared(chan, FTDM_CHANNEL_STATE_CHANGE, 5000);
if (ftdm_test_flag(chan, FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_log_chan(chan, FTDM_LOG_CRIT, "Failed to hangup, state change for %d/%s is still pending!\n", chan->state, ftdm_channel_state2str(chan->state));
return FTDM_FAIL;
}
}
ftdm_channel_set_state(file, func, line, chan, FTDM_CHANNEL_STATE_HANGUP, 1);
} else {
/* the signaling stack did not touch the state,
@ -2141,6 +2180,23 @@ FT_DECLARE(ftdm_status_t) ftdm_span_get_sig_status(ftdm_span_t *span, ftdm_signa
}
}
#ifdef FTDM_DEBUG_DTMF
static void close_dtmf_debug(ftdm_channel_t *ftdmchan)
{
ftdm_mutex_lock(ftdmchan->dtmfdbg.mutex);
if (ftdmchan->dtmfdbg.file) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "closing debug dtmf file\n");
fclose(ftdmchan->dtmfdbg.file);
ftdmchan->dtmfdbg.file = NULL;
}
ftdmchan->dtmfdbg.windex = 0;
ftdmchan->dtmfdbg.wrapped = 0;
ftdm_mutex_unlock(ftdmchan->dtmfdbg.mutex);
}
#endif
FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
{
assert(ftdmchan != NULL);
@ -2163,10 +2219,14 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_done(ftdm_channel_t *ftdmchan)
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_PROGRESS);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_MEDIA);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_ANSWERED);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_USER_HANGUP);
ftdm_mutex_lock(ftdmchan->pre_buffer_mutex);
ftdm_buffer_destroy(&ftdmchan->pre_buffer);
ftdmchan->pre_buffer_size = 0;
ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex);
#ifdef FTDM_DEBUG_DTMF
close_dtmf_debug(ftdmchan);
#endif
ftdmchan->init_state = FTDM_CHANNEL_STATE_DOWN;
ftdmchan->state = FTDM_CHANNEL_STATE_DOWN;
@ -2201,11 +2261,6 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan)
return FTDM_FAIL;
}
if (!ftdm_test_flag(check, FTDM_CHANNEL_INUSE)) {
ftdm_log(FTDM_LOG_WARNING, "Called ftdm_channel_close but never ftdm_channel_open in chan %d:%d??\n", check->span_id, check->chan_id);
return FTDM_FAIL;
}
if (ftdm_test_flag(check, FTDM_CHANNEL_CONFIGURED)) {
ftdm_mutex_lock(check->mutex);
if (ftdm_test_flag(check, FTDM_CHANNEL_OPEN)) {
@ -2215,6 +2270,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_close(ftdm_channel_t **ftdmchan)
ftdm_channel_reset(check);
*ftdmchan = NULL;
}
} else {
ftdm_log_chan_msg(check, FTDM_LOG_WARNING, "Called ftdm_channel_close but never ftdm_channel_open??\n");
}
check->ring_count = 0;
ftdm_mutex_unlock(check->mutex);
@ -2805,6 +2862,54 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_queue_dtmf(ftdm_channel_t *ftdmchan, cons
assert(ftdmchan != NULL);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Queuing DTMF %s\n", dtmf);
#ifdef FTDM_DEBUG_DTMF
ftdm_mutex_lock(ftdmchan->dtmfdbg.mutex);
if (!ftdmchan->dtmfdbg.file) {
struct tm currtime;
time_t currsec;
char dfile[512];
currsec = time(NULL);
localtime_r(&currsec, &currtime);
snprintf(dfile, sizeof(dfile), "dtmf-s%dc%d-20%d-%d-%d-%d:%d:%d.%s",
ftdmchan->span_id, ftdmchan->chan_id,
currtime.tm_year-100, currtime.tm_mon+1, currtime.tm_mday,
currtime.tm_hour, currtime.tm_min, currtime.tm_sec, ftdmchan->native_codec == FTDM_CODEC_ULAW ? "ulaw" : ftdmchan->native_codec == FTDM_CODEC_ALAW ? "alaw" : "sln");
ftdmchan->dtmfdbg.file = fopen(dfile, "w");
if (!ftdmchan->dtmfdbg.file) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "failed to open debug dtmf file %s\n", dfile);
} else {
/* write the saved audio buffer */
int rc = 0;
int towrite = sizeof(ftdmchan->dtmfdbg.buffer) - ftdmchan->dtmfdbg.windex;
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "created debug DTMF file %s\n", dfile);
ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT;
if (ftdmchan->dtmfdbg.wrapped) {
rc = fwrite(&ftdmchan->dtmfdbg.buffer[ftdmchan->dtmfdbg.windex], 1, towrite, ftdmchan->dtmfdbg.file);
if (rc != towrite) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite);
}
}
if (ftdmchan->dtmfdbg.windex) {
towrite = ftdmchan->dtmfdbg.windex;
rc = fwrite(&ftdmchan->dtmfdbg.buffer[0], 1, towrite, ftdmchan->dtmfdbg.file);
if (rc != towrite) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite);
}
}
ftdmchan->dtmfdbg.windex = 0;
ftdmchan->dtmfdbg.wrapped = 0;
}
} else {
ftdmchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT;
}
ftdm_mutex_unlock(ftdmchan->dtmfdbg.mutex);
#endif
if (ftdmchan->pre_buffer) {
ftdm_buffer_zero(ftdmchan->pre_buffer);
}
@ -2857,6 +2962,7 @@ static FIO_WRITE_FUNCTION(ftdm_raw_write)
return ftdmchan->fio->write(ftdmchan, data, datalen);
}
static FIO_READ_FUNCTION(ftdm_raw_read)
{
ftdm_status_t status = ftdmchan->fio->read(ftdmchan, data, datalen);
@ -2866,6 +2972,53 @@ static FIO_READ_FUNCTION(ftdm_raw_read)
ftdm_log(FTDM_LOG_WARNING, "Raw input trace failed to write all of the %zd bytes\n", dlen);
}
}
if (status == FTDM_SUCCESS && ftdmchan->span->sig_read) {
ftdmchan->span->sig_read(ftdmchan, data, *datalen);
}
#ifdef FTDM_DEBUG_DTMF
if (status == FTDM_SUCCESS) {
int dlen = (int) *datalen;
int rc = 0;
ftdm_mutex_lock(ftdmchan->dtmfdbg.mutex);
if (!ftdmchan->dtmfdbg.file) {
/* no file yet, write to our circular buffer */
int windex = ftdmchan->dtmfdbg.windex;
int avail = sizeof(ftdmchan->dtmfdbg.buffer) - windex;
char *dataptr = data;
if (dlen > avail) {
int diff = dlen - avail;
/* write only what we can and the rest at the beginning of the buffer */
memcpy(&ftdmchan->dtmfdbg.buffer[windex], dataptr, avail);
memcpy(&ftdmchan->dtmfdbg.buffer[0], &dataptr[avail], diff);
windex = diff;
/*ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "wrapping around dtmf read buffer up to index %d\n\n", windex);*/
ftdmchan->dtmfdbg.wrapped = 1;
} else {
memcpy(&ftdmchan->dtmfdbg.buffer[windex], dataptr, dlen);
windex += dlen;
}
if (windex == sizeof(ftdmchan->dtmfdbg.buffer)) {
/*ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "wrapping around dtmf read buffer\n");*/
windex = 0;
ftdmchan->dtmfdbg.wrapped = 1;
}
ftdmchan->dtmfdbg.windex = windex;
} else {
rc = fwrite(data, 1, dlen, ftdmchan->dtmfdbg.file);
if (rc != dlen) {
ftdm_log(FTDM_LOG_WARNING, "DTMF debugger wrote only %d out of %d bytes: %s\n", rc, datalen, strerror(errno));
}
ftdmchan->dtmfdbg.closetimeout--;
if (!ftdmchan->dtmfdbg.closetimeout) {
close_dtmf_debug(ftdmchan);
}
}
ftdm_mutex_unlock(ftdmchan->dtmfdbg.mutex);
}
#endif
return status;
}
@ -2980,17 +3133,21 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data
ftdm_assert_return(ftdmchan != NULL, FTDM_FAIL, "ftdmchan is null\n");
ftdm_assert_return(ftdmchan->fio != NULL, FTDM_FAIL, "No I/O module attached to ftdmchan\n");
ftdm_channel_lock(ftdmchan);
if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_OPEN)) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "channel not open");
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "cannot read from channel that is not open\n");
return FTDM_FAIL;
status = FTDM_FAIL;
goto done;
}
if (!ftdmchan->fio->read) {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "method not implemented");
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "read method not implemented\n");
return FTDM_FAIL;
status = FTDM_FAIL;
goto done;
}
status = ftdm_raw_read(ftdmchan, data, datalen);
@ -3059,7 +3216,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data
} else {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!");
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "invalid effective codec %d\n", ftdmchan->effective_codec);
return FTDM_FAIL;
status = FTDM_FAIL;
goto done;
}
}
sln = (int16_t *) sln_buf;
@ -3181,6 +3339,9 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data
ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex);
}
done:
ftdm_channel_unlock(ftdmchan);
return status;
}
@ -4214,6 +4375,13 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_HOLD);
break;
case FTDM_SIGEVENT_STOP:
if (ftdm_test_flag(sigmsg->channel, FTDM_CHANNEL_USER_HANGUP)) {
ftdm_log_chan_msg(sigmsg->channel, FTDM_LOG_DEBUG, "Ignoring SIGEVENT_STOP since user already requested hangup\n");
goto done;
}
break;
default:
break;
@ -4224,6 +4392,7 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
status = span->signal_cb(sigmsg);
}
done:
if (sigmsg->channel) {
ftdm_mutex_unlock(sigmsg->channel->mutex);
}

View File

@ -434,7 +434,7 @@ FT_DECLARE(ftdm_status_t) ftdm_interrupt_multiple_wait(ftdm_interrupt_t *interru
}
/* fall-through to FTDM_SUCCESS at the end of the function */
}
#elif defined(__linux__)
#elif defined(__linux__) || defined(__FreeBSD__)
int res = 0;
char pipebuf[255];
struct pollfd ints[size*2];

View File

@ -673,7 +673,6 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALTONE) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_COLLECT);
ftdm_clear_flag_locked(ftdmchan, FTDM_CHANNEL_STATE_CHANGE);
collecting = 1;
}
dtmf_offset = strlen(dtmf);

View File

@ -0,0 +1,926 @@
/*
* Copyright (c) 2010, Moises Silva <moy@sangoma.com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* * 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.
*
* * Neither the name of the original author; nor the names of any contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER
* 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.
*/
#include <libpri.h>
#include <poll.h>
#include "private/ftdm_core.h"
#define PRI_SPAN(p) (((p) >> 8) & 0xff)
#define PRI_CHANNEL(p) ((p) & 0xff)
typedef enum {
PRITAP_RUNNING = (1 << 0),
} pritap_flags_t;
typedef struct {
void *callref;
ftdm_number_t callingnum;
ftdm_number_t callingani;
ftdm_number_t callednum;
ftdm_channel_t *fchan;
char callingname[80];
int proceeding:1;
int inuse:1;
} passive_call_t;
typedef struct pritap {
int32_t flags;
struct pri *pri;
int debug;
ftdm_channel_t *dchan;
ftdm_span_t *span;
ftdm_span_t *peerspan;
ftdm_mutex_t *pcalls_lock;
passive_call_t pcalls[FTDM_MAX_CHANNELS_PHYSICAL_SPAN];
} pritap_t;
static FIO_IO_UNLOAD_FUNCTION(ftdm_pritap_unload)
{
return FTDM_SUCCESS;
}
static FIO_CHANNEL_GET_SIG_STATUS_FUNCTION(pritap_get_channel_sig_status)
{
*status = FTDM_SIG_STATE_UP;
return FTDM_SUCCESS;
}
static FIO_SPAN_GET_SIG_STATUS_FUNCTION(pritap_get_span_sig_status)
{
*status = FTDM_SIG_STATE_UP;
return FTDM_SUCCESS;
}
static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(pritap_outgoing_call)
{
ftdm_log(FTDM_LOG_ERROR, "Cannot dial on PRI tapping line!\n");
return FTDM_FAIL;
}
static void s_pri_error(struct pri *pri, char *s)
{
ftdm_log(FTDM_LOG_ERROR, "%s", s);
}
static void s_pri_message(struct pri *pri, char *s)
{
ftdm_log(FTDM_LOG_DEBUG, "%s", s);
}
static int parse_debug(const char *in)
{
int flags = 0;
if (!in) {
return 0;
}
if (strstr(in, "q921_raw")) {
flags |= PRI_DEBUG_Q921_RAW;
}
if (strstr(in, "q921_dump")) {
flags |= PRI_DEBUG_Q921_DUMP;
}
if (strstr(in, "q921_state")) {
flags |= PRI_DEBUG_Q921_STATE;
}
if (strstr(in, "config")) {
flags |= PRI_DEBUG_CONFIG;
}
if (strstr(in, "q931_dump")) {
flags |= PRI_DEBUG_Q931_DUMP;
}
if (strstr(in, "q931_state")) {
flags |= PRI_DEBUG_Q931_STATE;
}
if (strstr(in, "q931_anomaly")) {
flags |= PRI_DEBUG_Q931_ANOMALY;
}
if (strstr(in, "apdu")) {
flags |= PRI_DEBUG_APDU;
}
if (strstr(in, "aoc")) {
flags |= PRI_DEBUG_AOC;
}
if (strstr(in, "all")) {
flags |= PRI_DEBUG_ALL;
}
if (strstr(in, "none")) {
flags = 0;
}
return flags;
}
static ftdm_io_interface_t ftdm_pritap_interface;
static ftdm_status_t ftdm_pritap_start(ftdm_span_t *span);
static FIO_API_FUNCTION(ftdm_pritap_api)
{
char *mycmd = NULL, *argv[10] = { 0 };
int argc = 0;
if (data) {
mycmd = ftdm_strdup(data);
argc = ftdm_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
}
if (argc > 2) {
if (!strcasecmp(argv[0], "debug")) {
ftdm_span_t *span = NULL;
if (ftdm_span_find_by_name(argv[1], &span) == FTDM_SUCCESS) {
pritap_t *pritap = span->signal_data;
if (span->start != ftdm_pritap_start) {
stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__);
goto done;
}
pri_set_debug(pritap->pri, parse_debug(argv[2]));
stream->write_function(stream, "%s: +OK debug set.\n", __FILE__);
goto done;
} else {
stream->write_function(stream, "%s: -ERR invalid span.\n", __FILE__);
goto done;
}
}
}
stream->write_function(stream, "%s: -ERR invalid command.\n", __FILE__);
done:
ftdm_safe_free(mycmd);
return FTDM_SUCCESS;
}
static FIO_IO_LOAD_FUNCTION(ftdm_pritap_io_init)
{
memset(&ftdm_pritap_interface, 0, sizeof(ftdm_pritap_interface));
ftdm_pritap_interface.name = "pritap";
ftdm_pritap_interface.api = ftdm_pritap_api;
*fio = &ftdm_pritap_interface;
return FTDM_SUCCESS;
}
static FIO_SIG_LOAD_FUNCTION(ftdm_pritap_init)
{
pri_set_error(s_pri_error);
pri_set_message(s_pri_message);
return FTDM_SUCCESS;
}
static ftdm_state_map_t pritap_state_map = {
{
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_DOWN, FTDM_END},
{FTDM_CHANNEL_STATE_RING, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_RING, FTDM_END},
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END}
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_HANGUP, FTDM_END},
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
{FTDM_CHANNEL_STATE_DOWN, FTDM_END},
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_PROGRESS, FTDM_END},
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_CHANNEL_STATE_UP, FTDM_END},
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_PROGRESS_MEDIA, FTDM_END},
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_CHANNEL_STATE_UP, FTDM_END},
},
{
ZSD_INBOUND,
ZSM_UNACCEPTABLE,
{FTDM_CHANNEL_STATE_UP, FTDM_END},
{FTDM_CHANNEL_STATE_HANGUP, FTDM_CHANNEL_STATE_TERMINATING, FTDM_END},
},
}
};
static __inline__ void state_advance(ftdm_channel_t *ftdmchan)
{
ftdm_status_t status;
ftdm_sigmsg_t sig;
ftdm_channel_t *peerchan = ftdmchan->call_data;
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "processing state %s\n", ftdm_channel_state2str(ftdmchan->state));
memset(&sig, 0, sizeof(sig));
sig.chan_id = ftdmchan->chan_id;
sig.span_id = ftdmchan->span_id;
sig.channel = ftdmchan;
switch (ftdmchan->state) {
case FTDM_CHANNEL_STATE_DOWN:
{
ftdm_channel_done(ftdmchan);
ftdmchan->call_data = NULL;
ftdm_channel_done(peerchan);
peerchan->call_data = NULL;
}
break;
case FTDM_CHANNEL_STATE_PROGRESS:
case FTDM_CHANNEL_STATE_PROGRESS_MEDIA:
case FTDM_CHANNEL_STATE_UP:
case FTDM_CHANNEL_STATE_HANGUP:
break;
case FTDM_CHANNEL_STATE_RING:
{
sig.event_id = FTDM_SIGEVENT_START;
if ((status = ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS)) {
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP);
}
}
break;
case FTDM_CHANNEL_STATE_TERMINATING:
{
if (ftdmchan->last_state != FTDM_CHANNEL_STATE_HANGUP) {
sig.event_id = FTDM_SIGEVENT_STOP;
status = ftdm_span_send_signal(ftdmchan->span, &sig);
}
ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);
}
break;
default:
{
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "ignoring state change from %s to %s\n", ftdm_channel_state2str(ftdmchan->last_state), ftdm_channel_state2str(ftdmchan->state));
}
break;
}
return;
}
static __inline__ void pritap_check_state(ftdm_span_t *span)
{
if (ftdm_test_flag(span, FTDM_SPAN_STATE_CHANGE)) {
uint32_t j;
ftdm_clear_flag_locked(span, FTDM_SPAN_STATE_CHANGE);
for(j = 1; j <= span->chan_count; j++) {
if (ftdm_test_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE)) {
ftdm_mutex_lock(span->channels[j]->mutex);
ftdm_clear_flag((span->channels[j]), FTDM_CHANNEL_STATE_CHANGE);
state_advance(span->channels[j]);
ftdm_channel_complete_state(span->channels[j]);
ftdm_mutex_unlock(span->channels[j]->mutex);
}
}
}
}
static int pri_io_read(struct pri *pri, void *buf, int buflen)
{
int res;
ftdm_status_t zst;
pritap_t *pritap = pri_get_userdata(pri);
ftdm_size_t len = buflen;
if ((zst = ftdm_channel_read(pritap->dchan, buf, &len)) != FTDM_SUCCESS) {
if (zst == FTDM_FAIL) {
ftdm_log(FTDM_LOG_CRIT, "span %d D channel read fail! [%s]\n", pritap->span->span_id, pritap->dchan->last_error);
} else {
ftdm_log(FTDM_LOG_CRIT, "span %d D channel read timeout!\n", pritap->span->span_id);
}
return -1;
}
res = (int)len;
memset(&((unsigned char*)buf)[res],0,2);
res += 2;
return res;
}
static int pri_io_write(struct pri *pri, void *buf, int buflen)
{
pritap_t *pritap = pri_get_userdata(pri);
ftdm_size_t len = buflen - 2;
if (ftdm_channel_write(pritap->dchan, buf, buflen, &len) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_CRIT, "span %d D channel write failed! [%s]\n", pritap->span->span_id, pritap->dchan->last_error);
return -1;
}
return (int)buflen;
}
static int tap_pri_get_crv(struct pri *ctrl, q931_call *call)
{
int callmode = 0;
int crv = pri_get_crv(ctrl, call, &callmode);
crv <<= 3;
crv |= (callmode & 0x7);
return crv;
}
static passive_call_t *tap_pri_get_pcall_bycrv(pritap_t *pritap, int crv)
{
int i;
int tstcrv;
ftdm_mutex_lock(pritap->pcalls_lock);
for (i = 0; i < ftdm_array_len(pritap->pcalls); i++) {
tstcrv = pritap->pcalls[i].callref ? tap_pri_get_crv(pritap->pri, pritap->pcalls[i].callref) : 0;
if (pritap->pcalls[i].callref && tstcrv == crv) {
if (!pritap->pcalls[i].inuse) {
ftdm_log(FTDM_LOG_ERROR, "Found crv %d in slot %d of span %s with call %p but is no longer in use!\n",
crv, i, pritap->span->name, pritap->pcalls[i].callref);
continue;
}
ftdm_mutex_unlock(pritap->pcalls_lock);
return &pritap->pcalls[i];
}
}
ftdm_mutex_unlock(pritap->pcalls_lock);
return NULL;
}
static passive_call_t *tap_pri_get_pcall(pritap_t *pritap, void *callref)
{
int i;
int crv;
ftdm_mutex_lock(pritap->pcalls_lock);
for (i = 0; i < ftdm_array_len(pritap->pcalls); i++) {
if (pritap->pcalls[i].callref && !pritap->pcalls[i].inuse) {
crv = tap_pri_get_crv(pritap->pri, pritap->pcalls[i].callref);
/* garbage collection */
ftdm_log(FTDM_LOG_DEBUG, "Garbage collecting callref %d/%p from span %s in slot %d\n",
crv, pritap->pcalls[i].callref, pritap->span->name, i);
pri_passive_destroycall(pritap->pri, pritap->pcalls[i].callref);
memset(&pritap->pcalls[i], 0, sizeof(pritap->pcalls[0]));
}
if (callref == pritap->pcalls[i].callref) {
pritap->pcalls[i].inuse = 1;
ftdm_mutex_unlock(pritap->pcalls_lock);
return &pritap->pcalls[i];
}
}
ftdm_mutex_unlock(pritap->pcalls_lock);
return NULL;
}
static void tap_pri_put_pcall(pritap_t *pritap, void *callref)
{
int i;
int crv;
int tstcrv;
if (!callref) {
ftdm_log(FTDM_LOG_ERROR, "Cannot put pcall for null callref in span %s\n", pritap->span->name);
return;
}
ftdm_mutex_lock(pritap->pcalls_lock);
crv = tap_pri_get_crv(pritap->pri, callref);
for (i = 0; i < ftdm_array_len(pritap->pcalls); i++) {
if (!pritap->pcalls[i].callref) {
continue;
}
tstcrv = tap_pri_get_crv(pritap->pri, pritap->pcalls[i].callref);
if (tstcrv == crv) {
ftdm_log(FTDM_LOG_DEBUG, "releasing slot %d in span %s used by callref %d/%p\n", i,
pritap->span->name, crv, pritap->pcalls[i].callref);
if (!pritap->pcalls[i].inuse) {
ftdm_log(FTDM_LOG_ERROR, "slot %d in span %s used by callref %d/%p was released already?\n",
i, pritap->span->name, crv, pritap->pcalls[i].callref);
}
pritap->pcalls[i].inuse = 0;
}
}
ftdm_mutex_unlock(pritap->pcalls_lock);
}
static __inline__ ftdm_channel_t *tap_pri_get_fchan(pritap_t *pritap, passive_call_t *pcall, int channel)
{
ftdm_channel_t *fchan = NULL;
int chanpos = PRI_CHANNEL(channel);
if (!chanpos || chanpos > pritap->span->chan_count) {
ftdm_log(FTDM_LOG_CRIT, "Invalid pri tap channel %d requested in span %s\n", channel, pritap->span->name);
return NULL;
}
fchan = pritap->span->channels[PRI_CHANNEL(channel)];
if (ftdm_test_flag(fchan, FTDM_CHANNEL_INUSE)) {
ftdm_log(FTDM_LOG_ERROR, "Channel %d requested in span %s is already in use!\n", channel, pritap->span->name);
return NULL;
}
if (ftdm_channel_open_chan(fchan) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Could not open tap channel %d requested in span %s\n", channel, pritap->span->name);
return NULL;
}
memset(&fchan->caller_data, 0, sizeof(fchan->caller_data));
ftdm_set_string(fchan->caller_data.cid_num.digits, pcall->callingnum.digits);
if (!ftdm_strlen_zero(pcall->callingname)) {
ftdm_set_string(fchan->caller_data.cid_name, pcall->callingname);
} else {
ftdm_set_string(fchan->caller_data.cid_name, pcall->callingnum.digits);
}
ftdm_set_string(fchan->caller_data.ani.digits, pcall->callingani.digits);
ftdm_set_string(fchan->caller_data.dnis.digits, pcall->callednum.digits);
return fchan;
}
static void handle_pri_passive_event(pritap_t *pritap, pri_event *e)
{
passive_call_t *pcall = NULL;
passive_call_t *peerpcall = NULL;
ftdm_channel_t *fchan = NULL;
ftdm_channel_t *peerfchan = NULL;
int layer1, transcap = 0;
int crv = 0;
pritap_t *peertap = pritap->peerspan->signal_data;
switch (e->e) {
case PRI_EVENT_RING:
/* we cannot use ftdm_channel_t because we still dont know which channel will be used
* (ie, flexible channel was requested), thus, we need our own list of call references */
crv = tap_pri_get_crv(pritap->pri, e->ring.call);
ftdm_log(FTDM_LOG_DEBUG, "Ring on channel %s:%d:%d with callref %d\n",
pritap->span->name, PRI_SPAN(e->ring.channel), PRI_CHANNEL(e->ring.channel), crv);
pcall = tap_pri_get_pcall_bycrv(pritap, crv);
if (pcall) {
ftdm_log(FTDM_LOG_WARNING, "There is a call with callref %d already, ignoring duplicated ring event\n", crv);
break;
}
pcall = tap_pri_get_pcall(pritap, NULL);
if (!pcall) {
ftdm_log(FTDM_LOG_ERROR, "Failed to get a free passive PRI call slot for callref %d, this is a bug!\n", crv);
break;
}
pcall->callref = e->ring.call;
ftdm_set_string(pcall->callingnum.digits, e->ring.callingnum);
ftdm_set_string(pcall->callingani.digits, e->ring.callingani);
ftdm_set_string(pcall->callednum.digits, e->ring.callednum);
ftdm_set_string(pcall->callingname, e->ring.callingname);
break;
case PRI_EVENT_PROGRESS:
crv = tap_pri_get_crv(pritap->pri, e->ring.call);
ftdm_log(FTDM_LOG_DEBUG, "Progress on channel %s:%d:%d with callref %d\n",
pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
break;
case PRI_EVENT_PROCEEDING:
crv = tap_pri_get_crv(pritap->pri, e->proceeding.call);
/* at this point we should know the real b chan that will be used and can therefore proceed to notify about the call, but
* only if a couple of call tests are passed first */
ftdm_log(FTDM_LOG_DEBUG, "Proceeding on channel %s:%d:%d with callref %d\n",
pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
/* check that we already know about this call in the peer PRI (which was the one receiving the PRI_EVENT_RING event) */
if (!(pcall = tap_pri_get_pcall_bycrv(peertap, crv))) {
ftdm_log(FTDM_LOG_DEBUG,
"ignoring proceeding in channel %s:%d:%d for callref %d since we don't know about it",
pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
break;
}
if (pcall->proceeding) {
ftdm_log(FTDM_LOG_DEBUG, "Ignoring duplicated proceeding with callref %d\n", crv);
break;
}
peerpcall = tap_pri_get_pcall(pritap, NULL);
if (!peerpcall) {
ftdm_log(FTDM_LOG_ERROR, "Failed to get a free peer PRI passive call slot for callref %d in span %s, this is a bug!\n",
crv, pritap->span->name);
break;
}
peerpcall->callref = e->proceeding.call;
/* check that the layer 1 and trans capability are supported */
layer1 = pri_get_layer1(peertap->pri, pcall->callref);
transcap = pri_get_transcap(peertap->pri, pcall->callref);
if (PRI_LAYER_1_ULAW != layer1 && PRI_LAYER_1_ALAW != layer1) {
ftdm_log(FTDM_LOG_NOTICE, "Not monitoring callref %d with unsupported layer 1 format %d\n", crv, layer1);
break;
}
if (transcap != PRI_TRANS_CAP_SPEECH && transcap != PRI_TRANS_CAP_3_1K_AUDIO && transcap != PRI_TRANS_CAP_7K_AUDIO) {
ftdm_log(FTDM_LOG_NOTICE, "Not monitoring callref %d with unsupported capability %d\n", crv, transcap);
break;
}
fchan = tap_pri_get_fchan(pritap, pcall, e->proceeding.channel);
if (!fchan) {
ftdm_log(FTDM_LOG_ERROR, "Proceeding requested on odd/unavailable channel %s:%d:%d for callref %d\n",
pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
break;
}
pcall->fchan = fchan;
peerfchan = tap_pri_get_fchan(peertap, pcall, e->proceeding.channel);
if (!peerfchan) {
ftdm_log(FTDM_LOG_ERROR, "Proceeding requested on odd/unavailable channel %s:%d:%d for callref %d\n",
peertap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
break;
}
peerpcall->fchan = fchan;
fchan->call_data = peerfchan;
peerfchan->call_data = fchan;
ftdm_set_state_locked(fchan, FTDM_CHANNEL_STATE_RING);
break;
case PRI_EVENT_ANSWER:
crv = tap_pri_get_crv(pritap->pri, e->answer.call);
ftdm_log(FTDM_LOG_DEBUG, "Answer on channel %s:%d:%d with callref %d\n",
pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv);
if (!(pcall = tap_pri_get_pcall_bycrv(pritap, crv))) {
ftdm_log(FTDM_LOG_DEBUG,
"ignoring answer in channel %s:%d:%d for callref %d since we don't know about it",
pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
break;
}
ftdm_log_chan(pcall->fchan, FTDM_LOG_NOTICE, "Tapped call was answered in state %s\n", ftdm_channel_state2str(pcall->fchan->state));
break;
case PRI_EVENT_HANGUP_REQ:
crv = tap_pri_get_crv(pritap->pri, e->hangup.call);
ftdm_log(FTDM_LOG_DEBUG, "Hangup on channel %s:%d:%d with callref %d\n",
pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv);
if (!(pcall = tap_pri_get_pcall_bycrv(pritap, crv))) {
ftdm_log(FTDM_LOG_DEBUG,
"ignoring hangup in channel %s:%d:%d for callref %d since we don't know about it",
pritap->span->name, PRI_SPAN(e->proceeding.channel), PRI_CHANNEL(e->proceeding.channel), crv);
break;
}
fchan = pcall->fchan;
ftdm_set_state_locked(fchan, FTDM_CHANNEL_STATE_TERMINATING);
break;
case PRI_EVENT_HANGUP_ACK:
crv = tap_pri_get_crv(pritap->pri, e->hangup.call);
ftdm_log(FTDM_LOG_DEBUG, "Hangup ack on channel %s:%d:%d with callref %d\n",
pritap->span->name, PRI_SPAN(e->answer.channel), PRI_CHANNEL(e->answer.channel), crv);
tap_pri_put_pcall(pritap, e->hangup.call);
tap_pri_put_pcall(peertap, e->hangup.call);
break;
default:
ftdm_log(FTDM_LOG_DEBUG, "Ignoring passive event %s on span %s\n", pri_event2str(e->gen.e), pritap->span->name);
break;
}
}
static void *ftdm_pritap_run(ftdm_thread_t *me, void *obj)
{
ftdm_span_t *span = (ftdm_span_t *) obj;
pritap_t *pritap = span->signal_data;
pri_event *event = NULL;
struct pollfd dpoll = { 0, 0, 0 };
int rc = 0;
ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread started on span %d\n", span->span_id);
pritap->span = span;
ftdm_set_flag(span, FTDM_SPAN_IN_THREAD);
if (ftdm_channel_open(span->span_id, pritap->dchan->chan_id, &pritap->dchan) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Failed to open D-channel for span %s\n", span->name);
goto done;
}
if ((pritap->pri = pri_new_cb(pritap->dchan->sockfd, PRI_NETWORK, PRI_SWITCH_NI2, pri_io_read, pri_io_write, pritap))){
pri_set_debug(pritap->pri, pritap->debug);
} else {
ftdm_log(FTDM_LOG_CRIT, "Failed to create tapping PRI\n");
goto done;
}
dpoll.fd = pritap->dchan->sockfd;
while (ftdm_running() && !ftdm_test_flag(span, FTDM_SPAN_STOP_THREAD)) {
pritap_check_state(span);
dpoll.revents = 0;
dpoll.events = POLLIN;
rc = poll(&dpoll, 1, 10);
if (rc < 0) {
if (errno == EINTR) {
ftdm_log(FTDM_LOG_DEBUG, "D-channel waiting interrupted, continuing ...\n");
continue;
}
ftdm_log(FTDM_LOG_ERROR, "poll failed: %s\n", strerror(errno));
continue;
}
pri_schedule_run(pritap->pri);
if (rc) {
if (dpoll.revents & POLLIN) {
event = pri_read_event(pritap->pri);
if (event) {
handle_pri_passive_event(pritap, event);
}
} else {
ftdm_log(FTDM_LOG_WARNING, "nothing to read?\n");
}
}
pritap_check_state(span);
}
done:
ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI thread ended on span %d\n", span->span_id);
ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD);
ftdm_clear_flag(pritap, PRITAP_RUNNING);
return NULL;
}
static ftdm_status_t ftdm_pritap_stop(ftdm_span_t *span)
{
pritap_t *pritap = span->signal_data;
if (!ftdm_test_flag(pritap, PRITAP_RUNNING)) {
return FTDM_FAIL;
}
ftdm_set_flag(span, FTDM_SPAN_STOP_THREAD);
while (ftdm_test_flag(span, FTDM_SPAN_IN_THREAD)) {
ftdm_sleep(100);
}
ftdm_mutex_destroy(&pritap->pcalls_lock);
return FTDM_SUCCESS;
}
static ftdm_status_t ftdm_pritap_sig_read(ftdm_channel_t *ftdmchan, void *data, ftdm_size_t size)
{
ftdm_status_t status;
fio_codec_t codec_func;
ftdm_channel_t *peerchan = ftdmchan->call_data;
int16_t chanbuf[size];
int16_t peerbuf[size];
int16_t mixedbuf[size];
int i = 0;
ftdm_size_t sizeread = size;
if (!FTDM_IS_VOICE_CHANNEL(ftdmchan) || !ftdmchan->call_data) {
return FTDM_SUCCESS;
}
if (ftdmchan->native_codec != peerchan->native_codec) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Invalid peer channel with format %d, ours = %d\n",
peerchan->native_codec, ftdmchan->native_codec);
return FTDM_FAIL;
}
memcpy(chanbuf, data, size);
status = peerchan->fio->read(peerchan, peerbuf, &sizeread);
if (status != FTDM_SUCCESS) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_ERROR, "Failed to read from peer channel!\n");
return FTDM_FAIL;
}
if (sizeread != size) {
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "read from peer channel only %d bytes!\n", sizeread);
return FTDM_FAIL;
}
codec_func = peerchan->native_codec == FTDM_CODEC_ULAW ? fio_ulaw2slin : peerchan->native_codec == FTDM_CODEC_ALAW ? fio_alaw2slin : NULL;
if (codec_func) {
sizeread = size;
codec_func(chanbuf, sizeof(chanbuf), &sizeread);
sizeread = size;
codec_func(peerbuf, sizeof(peerbuf), &sizeread);
}
for (i = 0; i < size; i++) {
mixedbuf[i] = ftdm_saturated_add(chanbuf[i], peerbuf[i]);
}
codec_func = peerchan->native_codec == FTDM_CODEC_ULAW ? fio_slin2ulaw : peerchan->native_codec == FTDM_CODEC_ALAW ? fio_slin2alaw : NULL;
if (codec_func) {
size = sizeof(mixedbuf);
codec_func(mixedbuf, size, &size);
}
memcpy(data, mixedbuf, size);
return FTDM_SUCCESS;
}
static ftdm_status_t ftdm_pritap_start(ftdm_span_t *span)
{
ftdm_status_t ret;
pritap_t *pritap = span->signal_data;
if (ftdm_test_flag(pritap, PRITAP_RUNNING)) {
return FTDM_FAIL;
}
ftdm_mutex_create(&pritap->pcalls_lock);
ftdm_clear_flag(span, FTDM_SPAN_STOP_THREAD);
ftdm_clear_flag(span, FTDM_SPAN_IN_THREAD);
ftdm_set_flag(pritap, PRITAP_RUNNING);
ret = ftdm_thread_create_detached(ftdm_pritap_run, span);
if (ret != FTDM_SUCCESS) {
return ret;
}
return ret;
}
static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_pritap_configure_span)
{
uint32_t i;
const char *var, *val;
const char *debug = NULL;
ftdm_channel_t *dchan = NULL;
pritap_t *pritap = NULL;
ftdm_span_t *peerspan = NULL;
unsigned paramindex = 0;
if (span->trunk_type >= FTDM_TRUNK_NONE) {
ftdm_log(FTDM_LOG_WARNING, "Invalid trunk type '%s' defaulting to T1.\n", ftdm_trunk_type2str(span->trunk_type));
span->trunk_type = FTDM_TRUNK_T1;
}
for (i = 1; i <= span->chan_count; i++) {
if (span->channels[i]->type == FTDM_CHAN_TYPE_DQ921) {
dchan = span->channels[i];
}
}
if (!dchan) {
ftdm_log(FTDM_LOG_ERROR, "No d-channel specified in freetdm.conf!\n", ftdm_trunk_type2str(span->trunk_type));
return FTDM_FAIL;
}
for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) {
var = ftdm_parameters[paramindex].var;
val = ftdm_parameters[paramindex].val;
ftdm_log(FTDM_LOG_DEBUG, "Tapping PRI key=value, %s=%s\n", var, val);
if (!strcasecmp(var, "debug")) {
debug = val;
} else if (!strcasecmp(var, "peerspan")) {
if (ftdm_span_find_by_name(val, &peerspan) != FTDM_SUCCESS) {
ftdm_log(FTDM_LOG_ERROR, "Invalid tapping peer span %s\n", val);
break;
}
} else {
ftdm_log(FTDM_LOG_ERROR, "Unknown pri tapping parameter [%s]", var);
}
}
if (!peerspan) {
ftdm_log(FTDM_LOG_ERROR, "No valid peerspan was specified!\n");
return FTDM_FAIL;
}
pritap = ftdm_calloc(1, sizeof(*pritap));
if (!pritap) {
return FTDM_FAIL;
}
pritap->debug = parse_debug(debug);
pritap->dchan = dchan;
pritap->peerspan = peerspan;
span->start = ftdm_pritap_start;
span->stop = ftdm_pritap_stop;
span->sig_read = ftdm_pritap_sig_read;
span->signal_cb = sig_cb;
span->signal_data = pritap;
span->signal_type = FTDM_SIGTYPE_ISDN;
span->outgoing_call = pritap_outgoing_call;
span->get_channel_sig_status = pritap_get_channel_sig_status;
span->get_span_sig_status = pritap_get_span_sig_status;
span->state_map = &pritap_state_map;
return FTDM_SUCCESS;
}
/**
* \brief FreeTDM pritap signaling and IO module definition
*/
ftdm_module_t ftdm_module = {
"pritap",
ftdm_pritap_io_init,
ftdm_pritap_unload,
ftdm_pritap_init,
NULL,
NULL,
ftdm_pritap_configure_span,
};
/* For Emacs:
* Local Variables:
* mode:c
* indent-tabs-mode:t
* tab-width:4
* c-basic-offset:4
* End:
* For VIM:
* vim:set softtabstop=4 shiftwidth=4 tabstop=4:
*/

View File

@ -427,6 +427,10 @@ static FIO_CHANNEL_REQUEST_FUNCTION(sangoma_boost_channel_request)
event.called.ton = caller_data->dnis.type;
event.called.npi = caller_data->dnis.plan;
/* we're making a contract now that FreeTDM values for capability, layer 1 and such will be the same as for boost */
event.bearer.capability = caller_data->bearer_capability;
event.bearer.uil1p = caller_data->bearer_layer1;
if (caller_data->raw_data_len) {
ftdm_set_string(event.custom_data, caller_data->raw_data);
event.custom_data_size = (uint16_t)caller_data->raw_data_len;
@ -1055,6 +1059,9 @@ tryagain:
ftdmchan->caller_data.screen = event->calling.screening_ind;
ftdmchan->caller_data.pres = event->calling.presentation_ind;
ftdmchan->caller_data.bearer_capability = event->bearer.capability;
ftdmchan->caller_data.bearer_layer1 = event->bearer.uil1p;
/* more info about custom data: http://www.ss7box.com/smg_manual.html#ISUP-IN-RDNIS-NEW */
if (event->custom_data_size) {
char* p = NULL;

View File

@ -991,10 +991,9 @@ static FIO_GET_ALARMS_FUNCTION(wanpipe_get_alarms)
alarms &= ~WAN_TE_BIT_ALARM_RAI;
}
/* if we still have alarms that we did not map, set the general alarm */
if (alarms) {
/* FIXME: investigate what else does the driver report */
ftdm_log(FTDM_LOG_DEBUG, "Unmapped wanpipe alarms: %d\n", alarms);
ftdmchan->alarm_flags |= FTDM_ALARM_GENERAL;
}
return FTDM_SUCCESS;

View File

@ -254,6 +254,11 @@ typedef struct ftdm_caller_data {
int hangup_cause; /*!< Hangup cause */
char raw_data[1024]; /*!< Protocol specific raw caller data */
uint32_t raw_data_len; /* !< Raw data length */
/* these 2 are undocumented right now, only used by boost: */
/* bearer capability */
uint8_t bearer_capability;
/* user information layer 1 protocol */
uint8_t bearer_layer1;
} ftdm_caller_data_t;
/*! \brief Tone type */

View File

@ -340,6 +340,21 @@ typedef enum {
FTDM_TYPE_CHANNEL
} ftdm_data_type_t;
#ifdef FTDM_DEBUG_DTMF
/* number of bytes for the circular buffer (5 seconds worth of audio) */
#define DTMF_DEBUG_SIZE 8 * 5000
/* number of 20ms cycles before timeout and close the debug dtmf file (5 seconds) */
#define DTMF_DEBUG_TIMEOUT 250
typedef struct {
FILE *file;
char buffer[DTMF_DEBUG_SIZE];
int windex;
int wrapped;
int closetimeout;
ftdm_mutex_t *mutex;
} ftdm_dtmf_debug_t;
#endif
/* 2^8 table size, one for each byte (sample) value */
#define FTDM_GAINS_TABLE_SIZE 256
struct ftdm_channel {
@ -409,6 +424,9 @@ struct ftdm_channel {
float txgain;
int availability_rate;
void *user_private;
#ifdef FTDM_DEBUG_DTMF
ftdm_dtmf_debug_t dtmfdbg;
#endif
};
struct ftdm_span {
@ -439,6 +457,7 @@ struct ftdm_span {
fio_channel_request_t channel_request;
ftdm_span_start_t start;
ftdm_span_stop_t stop;
ftdm_channel_sig_read_t sig_read;
void *mod_data;
char *type;
char *dtmf_hangup;
@ -651,6 +670,18 @@ static __inline__ void ftdm_clear_flag_all(ftdm_span_t *span, uint32_t flag)
ftdm_mutex_unlock(span->mutex);
}
static __inline__ int16_t ftdm_saturated_add(int16_t sample1, int16_t sample2)
{
int addres;
addres = sample1 + sample2;
if (addres > 32767)
addres = 32767;
else if (addres < -32767)
addres = -32767;
return (int16_t)addres;
}
#ifdef __cplusplus
}
#endif

View File

@ -250,6 +250,7 @@ typedef enum {
FTDM_CHANNEL_USE_TX_GAIN = (1 << 26),
FTDM_CHANNEL_IN_ALARM = (1 << 27),
FTDM_CHANNEL_SIG_UP = (1 << 28),
FTDM_CHANNEL_USER_HANGUP = (1 << 29),
} ftdm_channel_flag_t;
#if defined(__cplusplus) && defined(WIN32)
// fix C2676
@ -359,6 +360,7 @@ typedef struct ftdm_bitstream ftdm_bitstream_t;
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);
#ifdef __cplusplus
}

View File

@ -45,6 +45,9 @@ COMPILE = $(CC) $(MY_CFLAGS) $(INCS)
LTCOMPILE = $(LIBTOOL) --mode=compile --tag=CC $(COMPILE)
LINK = $(LIBTOOL) --mode=link --tag=CC $(CC) $(MY_CFLAGS) $(LDFLAGS) -o $@
if DEBUGDTMF
MY_CFLAGS += -DZAP_DEBUG_DTMF
endif
#
# GNU pkgconfig file

View File

@ -165,11 +165,18 @@ AC_ARG_WITH([libpri],
[AS_HELP_STRING([--with-libpri], [Install ozmod_libpri])], [enable_libpri="yes"], [enable_libpri="no"])
AC_SUBST(enable_libpri)
# debug dtmf?
AC_ARG_WITH([debugdtmf],
[AS_HELP_STRING([--with-debugdtmf], [Debug DTMF])], [enable_debugdtmf="yes"], [enable_debugdtmf="no"])
AC_SUBST(enable_debugdtmf)
AC_CHECK_LIB([sangoma], [sangoma_span_chan_toif], [have_libsangoma="yes"])
AM_CONDITIONAL([LIBSANGOMA],[test "${have_libsangoma}" = "yes"])
AM_CONDITIONAL([LIBPRI],[test "${enable_libpri}" = "yes"])
AM_CONDITIONAL([DEBUGDTMF],[test "${enable_debugdtmf}" = "yes"])
AC_CHECK_LIB([openr2], [openr2_context_set_io_type], [have_openr2="yes"])
AM_CONDITIONAL([OPENR2],[test "${have_openr2}" = "yes"])

View File

@ -254,6 +254,9 @@
#define zap_clear_sflag_locked(obj, flag) assert(obj->mutex != NULL); zap_mutex_lock(obj->mutex); (obj)->sflags &= ~(flag); zap_mutex_unlock(obj->mutex);
#define zap_log_chan(zchan, level, format, ...) zap_log(level, "[s%dc%d][%d:%d] " format, zchan->span_id, zchan->chan_id, zchan->physical_span_id, zchan->physical_chan_id, __VA_ARGS__)
#define zap_log_chan_msg(zchan, level, msg) zap_log(level, "[s%dc%d][%d:%d] " msg, zchan->span_id, zchan->chan_id, zchan->physical_span_id, zchan->physical_chan_id)
#define zap_set_state_locked(obj, s) if ( obj->state == s ) { \
if (s != ZAP_CHANNEL_STATE_HANGUP) zap_log(ZAP_LOG_WARNING, "Why bother changing state on %d:%d from %s to %s\n", obj->span_id, obj->chan_id, zap_channel_state2str(obj->state), zap_channel_state2str(s)); \
@ -494,6 +497,21 @@ typedef enum {
ZAP_TYPE_CHANNEL
} zap_data_type_t;
#ifdef ZAP_DEBUG_DTMF
/* number of bytes for the circular buffer (5 seconds worth of audio) */
#define DTMF_DEBUG_SIZE 8 * 5000
/* number of 20ms cycles before timeout and close the debug dtmf file (5 seconds) */
#define DTMF_DEBUG_TIMEOUT 250
typedef struct {
FILE *file;
char buffer[DTMF_DEBUG_SIZE];
int windex;
int wrapped;
int closetimeout;
zap_mutex_t *mutex;
} zap_dtmf_debug_t;
#endif
/* 2^8 table size, one for each byte value */
#define ZAP_GAINS_TABLE_SIZE 256
struct zap_channel {
@ -561,6 +579,9 @@ struct zap_channel {
unsigned char txgain_table[ZAP_GAINS_TABLE_SIZE];
float rxgain;
float txgain;
#ifdef ZAP_DEBUG_DTMF
zap_dtmf_debug_t dtmfdbg;
#endif
};

View File

@ -316,6 +316,9 @@ static zap_status_t zap_channel_destroy(zap_channel_t *zchan)
zap_sleep(500);
}
#ifdef ZAP_DEBUG_DTMF
zap_mutex_destroy(&zchan->dtmfdbg.mutex);
#endif
zap_mutex_lock(zchan->pre_buffer_mutex);
zap_buffer_destroy(&zchan->pre_buffer);
zap_mutex_unlock(zchan->pre_buffer_mutex);
@ -450,7 +453,7 @@ OZ_DECLARE(zap_status_t) zap_span_create(zap_io_interface_t *zio, zap_span_t **s
memset(new_span, 0, sizeof(*new_span));
status = zap_mutex_create(&new_span->mutex);
assert(status == ZAP_SUCCESS);
zap_set_flag(new_span, ZAP_SPAN_CONFIGURED);
new_span->span_id = ++globals.span_index;
new_span->zio = zio;
@ -658,6 +661,9 @@ OZ_DECLARE(zap_status_t) zap_span_add_channel(zap_span_t *span, zap_socket_t soc
zap_mutex_create(&new_chan->mutex);
zap_mutex_create(&new_chan->pre_buffer_mutex);
#ifdef ZAP_DEBUG_DTMF
zap_mutex_create(&new_chan->dtmfdbg.mutex);
#endif
zap_buffer_create(&new_chan->digit_buffer, 128, 128, 0);
zap_buffer_create(&new_chan->gen_dtmf_buffer, 128, 128, 0);
@ -1356,6 +1362,23 @@ OZ_DECLARE(zap_status_t) zap_channel_outgoing_call(zap_channel_t *zchan)
return ZAP_FAIL;
}
#ifdef ZAP_DEBUG_DTMF
static void close_dtmf_debug(zap_channel_t *zchan)
{
zap_mutex_lock(zchan->dtmfdbg.mutex);
if (zchan->dtmfdbg.file) {
zap_log_chan_msg(zchan, ZAP_LOG_DEBUG, "closing debug dtmf file\n");
fclose(zchan->dtmfdbg.file);
zchan->dtmfdbg.file = NULL;
}
zchan->dtmfdbg.windex = 0;
zchan->dtmfdbg.wrapped = 0;
zap_mutex_unlock(zchan->dtmfdbg.mutex);
}
#endif
OZ_DECLARE(zap_status_t) zap_channel_done(zap_channel_t *zchan)
{
assert(zchan != NULL);
@ -1380,6 +1403,9 @@ OZ_DECLARE(zap_status_t) zap_channel_done(zap_channel_t *zchan)
zap_buffer_destroy(&zchan->pre_buffer);
zchan->pre_buffer_size = 0;
zap_mutex_unlock(zchan->pre_buffer_mutex);
#ifdef ZAP_DEBUG_DTMF
close_dtmf_debug(zchan);
#endif
zap_channel_flush_dtmf(zchan);
@ -2001,6 +2027,54 @@ OZ_DECLARE(zap_status_t) zap_channel_queue_dtmf(zap_channel_t *zchan, const char
assert(zchan != NULL);
zap_log_chan(zchan, ZAP_LOG_DEBUG, "Queuing DTMF %s\n", dtmf);
#ifdef ZAP_DEBUG_DTMF
zap_mutex_lock(zchan->dtmfdbg.mutex);
if (!zchan->dtmfdbg.file) {
struct tm currtime;
time_t currsec;
char dfile[512];
currsec = time(NULL);
localtime_r(&currsec, &currtime);
snprintf(dfile, sizeof(dfile), "dtmf-s%dc%d-20%d-%d-%d-%d:%d:%d.%s",
zchan->span_id, zchan->chan_id,
currtime.tm_year-100, currtime.tm_mon+1, currtime.tm_mday,
currtime.tm_hour, currtime.tm_min, currtime.tm_sec, zchan->native_codec == ZAP_CODEC_ULAW ? "ulaw" : zchan->native_codec == ZAP_CODEC_ALAW ? "alaw" : "sln");
zchan->dtmfdbg.file = fopen(dfile, "w");
if (!zchan->dtmfdbg.file) {
zap_log_chan(zchan, ZAP_LOG_ERROR, "failed to open debug dtmf file %s\n", dfile);
} else {
/* write the saved audio buffer */
int rc = 0;
int towrite = sizeof(zchan->dtmfdbg.buffer) - zchan->dtmfdbg.windex;
zap_log_chan(zchan, ZAP_LOG_DEBUG, "created debug DTMF file %s\n", dfile);
zchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT;
if (zchan->dtmfdbg.wrapped) {
rc = fwrite(&zchan->dtmfdbg.buffer[zchan->dtmfdbg.windex], 1, towrite, zchan->dtmfdbg.file);
if (rc != towrite) {
zap_log_chan(zchan, ZAP_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite);
}
}
if (zchan->dtmfdbg.windex) {
towrite = zchan->dtmfdbg.windex;
rc = fwrite(&zchan->dtmfdbg.buffer[0], 1, towrite, zchan->dtmfdbg.file);
if (rc != towrite) {
zap_log_chan(zchan, ZAP_LOG_ERROR, "only wrote %d out of %d bytes in DTMF debug buffer\n", rc, towrite);
}
}
zchan->dtmfdbg.windex = 0;
zchan->dtmfdbg.wrapped = 0;
}
} else {
zchan->dtmfdbg.closetimeout = DTMF_DEBUG_TIMEOUT;
}
zap_mutex_unlock(zchan->dtmfdbg.mutex);
#endif
if (zchan->pre_buffer) {
zap_buffer_zero(zchan->pre_buffer);
}
@ -2177,6 +2251,49 @@ OZ_DECLARE(zap_status_t) zap_channel_read(zap_channel_t *zchan, void *data, zap_
}
}
#ifdef ZAP_DEBUG_DTMF
if (status == ZAP_SUCCESS) {
int dlen = (int) *datalen;
int rc = 0;
zap_mutex_lock(zchan->dtmfdbg.mutex);
if (!zchan->dtmfdbg.file) {
/* no file yet, write to our circular buffer */
int windex = zchan->dtmfdbg.windex;
int avail = sizeof(zchan->dtmfdbg.buffer) - windex;
char *dataptr = data;
if (dlen > avail) {
int diff = dlen - avail;
/* write only what we can and the rest at the beginning of the buffer */
memcpy(&zchan->dtmfdbg.buffer[windex], dataptr, avail);
memcpy(&zchan->dtmfdbg.buffer[0], &dataptr[avail], diff);
windex = diff;
/*zap_log_chan(zchan, ZAP_LOG_DEBUG, "wrapping around dtmf read buffer up to index %d\n\n", windex);*/
zchan->dtmfdbg.wrapped = 1;
} else {
memcpy(&zchan->dtmfdbg.buffer[windex], dataptr, dlen);
windex += dlen;
}
if (windex == sizeof(zchan->dtmfdbg.buffer)) {
/*zap_log_chan_msg(zchan, ZAP_LOG_DEBUG, "wrapping around dtmf read buffer\n");*/
windex = 0;
zchan->dtmfdbg.wrapped = 1;
}
zchan->dtmfdbg.windex = windex;
} else {
rc = fwrite(data, 1, dlen, zchan->dtmfdbg.file);
if (rc != dlen) {
zap_log(ZAP_LOG_WARNING, "DTMF debugger wrote only %d out of %d bytes: %s\n", rc, datalen, strerror(errno));
}
zchan->dtmfdbg.closetimeout--;
if (!zchan->dtmfdbg.closetimeout) {
close_dtmf_debug(zchan);
}
}
zap_mutex_unlock(zchan->dtmfdbg.mutex);
}
#endif
if (status == ZAP_SUCCESS) {
if (zap_test_flag(zchan, ZAP_CHANNEL_USE_RX_GAIN)
&& (zchan->native_codec == ZAP_CODEC_ALAW || zchan->native_codec == ZAP_CODEC_ULAW)) {

View File

@ -327,7 +327,7 @@ void *msg_buf_move(msg_t *dst, msg_t const *src)
* @param[in] msg message object
* @param[out] vec I/O vector
* @param[in] veclen available length of @a vec
* @param[in] n number of possibly available bytes 
* @param[in] n number of possibly available bytes
* @param[in] exact true if data ends at message boundary
*
* @return

View File

@ -89,7 +89,7 @@ su_log_t nua_log[] = { SU_LOG_INIT("nua", "NUA_DEBUG", SU_DEBUG) };
* @param root Pointer to a root object
* @param callback Pointer to event callback function
* @param magic Pointer to callback context
* @param tag, value, ... List of tagged parameters
* @param tag, value, ... List of tagged parameters
*
* @retval !=NULL a pointer to a @nua stack object
* @retval NULL upon an error

View File

@ -704,7 +704,7 @@ int nua_notify_client_request(nua_client_request_t *cr,
if (sr->sr_usage == du) {
/* If subscribe has not been responded, don't terminate usage by NOTIFY */
sr->sr_terminating = 1;
nua_client_set_terminating(cr, 0);
// nua_client_set_terminating(cr, 0);
break;
}
}

View File

@ -15,8 +15,6 @@
## You should have received a copy of the GNU Lesser General Public
## License along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##
## $Id: Makefile.am,v 1.49 2009/05/30 05:55:22 steveu Exp $
AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
@ -37,9 +35,9 @@ EXTRA_DIST = autogen.sh \
debian/rules \
debian/watch \
README.testdata \
spandsp.pc \
spandsp.spec \
spandsp/fax-tests.dtd \
spandsp/fax-tests.xml \
spandsp/global-tones.xml \
spandsp/tones.dtd \
spandsp/tsb85.xml \

View File

@ -16,9 +16,6 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# $Id: autogen.sh,v 1.6 2008/03/30 18:33:24 steveu Exp $
#
UNAME=`uname`

View File

@ -15,17 +15,11 @@
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
# $Id: configure.ac,v 1.73 2009/10/03 04:37:25 steveu Exp $
# @start 1
AC_INIT
CFLAGS="$CFLAGS $CONFIGURE_CFLAGS"
CXXFLAGS="$CXXFLAGS $CONFIGURE_CXXFLAGS"
LDFLAGS="$LDFLAGS $CONFIGURE_LDFLAGS"
m4_include(config/ax_compiler_vendor.m4)
m4_include(config/ax_check_real_file.m4)
m4_include(config/ax_fixed_point_machine.m4)
@ -209,7 +203,9 @@ AC_CHECK_HEADERS([sys/select.h])
AC_CHECK_HEADERS([sys/ioctl.h])
AC_CHECK_HEADERS([sys/fcntl.h])
AC_CHECK_HEADERS([sndfile.h])
AC_CHECK_HEADERS([fenv.h])
AC_CHECK_HEADERS([fftw3.h], , [AC_CHECK_HEADERS([fftw.h])])
AC_CHECK_HEADERS([pcap.h])
AC_CHECK_HEADERS([pthread.h])
if test "${build}" == "${host}"
then
@ -270,6 +266,11 @@ then
esac
fi
#AC_DEFINE([SPANDSP_SUPPORT_T85], [1], [Support T.85 JBIG compression])
SPANDSP_SUPPORT_T85="#undef SPANDSP_SUPPORT_T85"
#AC_DEFINE([SPANDSP_SUPPORT_V34], [1], [Support the V.34 FAX modem])
SPANDSP_SUPPORT_V34="#undef SPANDSP_SUPPORT_V34"
AC_CHECK_LIB([m], [cos])
# Some platforms still seem to lack the basic single precision trig and power related function.
AC_SEARCH_LIBS([sinf], [m], AC_DEFINE([HAVE_SINF], [1], [Define to 1 if you have the sinf() function.]))
@ -293,6 +294,7 @@ if test -n "$enable_tests" ; then
AC_LANG([C])
AC_CHECK_LIB([sndfile], [sf_open], SIMLIBS="$SIMLIBS -lsndfile", AC_MSG_ERROR("Can't make tests without libsndfile (does your system require a libsndfile-devel package?)"))
AC_CHECK_LIB([fftw3], [fftw_plan_dft_1d], SIMLIBS="$SIMLIBS -lfftw3", [AC_CHECK_LIB([fftw], [fftw_create_plan], SIMLIBS="$SIMLIBS -lfftw", AC_MSG_ERROR("Can't make tests without FFTW 2 or 3 (does your system require an fftw?-devel package?)"))])
AC_CHECK_LIB([pcap], [pcap_open_offline], TESTLIBS="$TESTLIBS -lpcap", AC_MSG_ERROR("Can't make tests without libpcap (does your system require a libpcap-devel package?)"))
AC_CHECK_LIB([pthread], [pthread_attr_init], TESTLIBS="$TESTLIBS -lpthread")
AC_CHECK_LIB([dl], [dlopen], TESTLIBS="$TESTLIBS -ldl")
AC_CHECK_LIB([Xft], [XftFontOpen], TESTLIBS="$TESTLIBS -lXft",, $TESTLIBS)
@ -366,6 +368,37 @@ sun)
COMP_VENDOR_LDFLAGS=
REMOVE_FROM_VAR(CFLAGS, -Xc)
;;
intel)
COMP_VENDOR_CFLAGS="-std=c99 -D_POSIX_C_SOURCE=2 -D_GNU_SOURCE=1 -Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes $COMP_VENDOR_CFLAGS"
if test "$enable_sse5" = "yes" ; then
COMP_VENDOR_CFLAGS="-msse5 $COMP_VENDOR_CFLAGS"
fi
if test "$enable_sse4a" = "yes" ; then
COMP_VENDOR_CFLAGS="-msse4a $COMP_VENDOR_CFLAGS"
fi
if test "$enable_sse4_2" = "yes" ; then
COMP_VENDOR_CFLAGS="-msse42 $COMP_VENDOR_CFLAGS"
fi
if test "$enable_sse4_1" = "yes" ; then
COMP_VENDOR_CFLAGS="-msse41 $COMP_VENDOR_CFLAGS"
fi
if test "$enable_ssse3" = "yes" ; then
COMP_VENDOR_CFLAGS="-mssse3 $COMP_VENDOR_CFLAGS"
fi
if test "$enable_sse3" = "yes" ; then
COMP_VENDOR_CFLAGS="-msse3 $COMP_VENDOR_CFLAGS"
fi
if test "$enable_sse2" = "yes" ; then
COMP_VENDOR_CFLAGS="-msse2 $COMP_VENDOR_CFLAGS"
fi
if test "$enable_sse" = "yes" ; then
COMP_VENDOR_CFLAGS="-msse $COMP_VENDOR_CFLAGS"
fi
if test "$enable_mmx" = "yes" ; then
COMP_VENDOR_CFLAGS="-mmmx $COMP_VENDOR_CFLAGS"
fi
COMP_VENDOR_LDFLAGS=
;;
*)
COMP_VENDOR_CFLAGS="-std=c99 -Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes $COMP_VENDOR_CFLAGS"
COMP_VENDOR_LDFLAGS=
@ -438,15 +471,13 @@ fi
if test "$enable_builtin_tiff" = "yes" ; then
abs_tiffdir="`cd $srcdir/../tiff-3.8.2/ && pwd`"
spandsp_builddir="`pwd`"
abs_tiffbuilddir="`cd $spandsp_builddir/../tiff-3.8.2/ && pwd`"
save_CFLAGS=$CFLAGS
CFLAGS="$CFLAGS -I$abs_tiffdir/libtiff"
AC_CHECK_HEADERS([tiffio.h])
CFLAGS="$save_CFLAGS"
COMP_VENDOR_CFLAGS="-I$abs_tiffdir/libtiff $COMP_VENDOR_CFLAGS"
COMP_VENDOR_LDFLAGS="-L$abs_tiffdir/libtiff $COMP_VENDOR_LDFLAGS"
LIBS="$LIBS $abs_tiffbuilddir/libtiff/libtiff.la"
LIBS="$LIBS $abs_tiffdir/libtiff/libtiff.la"
AC_DEFINE([HAVE_LIBTIFF], [1], [Define to 1 if you have the `tiff' library (-ltiff).])
else
AC_CHECK_HEADERS([tiffio.h])
@ -464,6 +495,8 @@ AC_SUBST(TESTLIBS)
AC_SUBST(SPANDSP_USE_FIXED_POINT)
AC_SUBST(SPANDSP_MISALIGNED_ACCESS_FAILS)
AC_SUBST(SPANDSP_USE_EXPORT_CAPABILITY)
AC_SUBST(SPANDSP_SUPPORT_T85)
AC_SUBST(SPANDSP_SUPPORT_V34)
AC_SUBST(INSERT_INTTYPES_HEADER)
AC_SUBST(INSERT_STDINT_HEADER)
AC_SUBST(INSERT_TGMATH_HEADER)

View File

@ -15,8 +15,6 @@
## You should have received a copy of the GNU Lesser General Public
## License along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##
## $Id: Makefile.am,v 1.12 2008/09/20 15:44:40 steveu Exp $
MAINTAINERCLEANFILES = Makefile.in

View File

@ -1,7 +1,6 @@
<?xml version="1.0" encoding="iso8859-1"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
<!-- $Id: t38_manual.xml,v 1.5 2007/12/08 16:25:17 steveu Exp $ -->
<book>
<bookinfo>
<date>2007-11-14</date>

View File

@ -15,8 +15,6 @@
## You should have received a copy of the GNU General Public License
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##
## $Id: Makefile.am,v 1.10 2009/06/02 16:03:55 steveu Exp $
AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: g1050.c,v 1.17 2009/06/02 14:55:36 steveu Exp $
*/
#if defined(HAVE_CONFIG_H)

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: line_model.c,v 1.14 2009/09/23 16:02:59 steveu Exp $
*/
#if defined(HAVE_CONFIG_H)
@ -505,12 +503,15 @@ SPAN_DECLARE(int) one_way_line_model_release(one_way_line_model_state_t *s)
SPAN_DECLARE(both_ways_line_model_state_t *) both_ways_line_model_init(int model1,
float noise1,
float echo_level_cpe1,
float echo_level_co1,
int model2,
float noise2,
float echo_level_cpe2,
float echo_level_co2,
int codec,
int rbs_pattern)
{
float echo_level;
both_ways_line_model_state_t *s;
if ((s = (both_ways_line_model_state_t *) malloc(sizeof(*s))) == NULL)
@ -549,11 +550,10 @@ SPAN_DECLARE(both_ways_line_model_state_t *) both_ways_line_model_init(int model
s->line2.mains_interference = 0;
/* Echos */
echo_level = -15; /* in dB */
s->line1.near_co_hybrid_echo = pow(10, echo_level/20.0f);
s->line2.near_co_hybrid_echo = pow(10, echo_level/20.0f);
s->line1.near_cpe_hybrid_echo = pow(10, echo_level/20.0f);
s->line2.near_cpe_hybrid_echo = pow(10, echo_level/20.0f);
s->line1.near_co_hybrid_echo = pow(10, echo_level_co1/20.0f);
s->line2.near_co_hybrid_echo = pow(10, echo_level_co2/20.0f);
s->line1.near_cpe_hybrid_echo = pow(10, echo_level_cpe1/20.0f);
s->line2.near_cpe_hybrid_echo = pow(10, echo_level_cpe2/20.0f);
return s;
}

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: make_line_models.c,v 1.10 2009/09/23 16:02:59 steveu Exp $
*/
/*! \page make_line_models_page Telephony line model construction

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: rfc2198_sim.c,v 1.10 2009/06/01 16:27:12 steveu Exp $
*/
#if defined(HAVE_CONFIG_H)

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: spandsp-sim.h,v 1.5 2008/04/26 13:39:16 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: g1050.h,v 1.12 2009/06/01 16:27:12 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: line_model.h,v 1.7.4.1 2009/12/19 10:16:44 steveu Exp $
*/
/*! \file */
@ -147,8 +145,12 @@ SPAN_DECLARE(void) both_ways_line_model_set_mains_pickup(both_ways_line_model_st
SPAN_DECLARE(both_ways_line_model_state_t *) both_ways_line_model_init(int model1,
float noise1,
float echo_level_cpe1,
float echo_level_co1,
int model2,
float noise2,
float echo_level_cpe2,
float echo_level_co2,
int codec,
int rbs_pattern);

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: line_models.h,v 1.3 2008/04/17 18:03:23 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: rfc2198_sim.h,v 1.6 2009/05/31 14:47:10 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: test_utils.h,v 1.9 2009/05/31 14:47:10 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: test_utils.c,v 1.14 2009/06/01 16:27:12 steveu Exp $
*/
/*! \file */

View File

@ -0,0 +1,96 @@
<?xml version="1.0"?>
<!DOCTYPE fax-tests SYSTEM "./fax-tests.dtd">
<fax-tests>
<config>
<path type="IMAGE" value="../test-data/etsi/fax"/>
</config>
<messages>
<!-- TCF = 2700 bytes at 14400, 2250 at 12000, 1800 at 9600, 1350 at 7200, 900 at 4800 or 450 at 2400 -->
<!-- Bad TCF == 10101010.... -->
<!-- slow HDLC preamble == 37 flag bytes -->
<!-- slow HDLC inter-frame flag sequence == 1 flag byte -->
<!-- slow HDLC end flag sequence == 5 flag bytes -->
<!-- synchronisation sequence == 250ms of zeros. = 450 bytes at 14400, 375 at 12000, 300 at 9600, 225 at 7200, 150 at 4800 or 75 at 2400 -->
<!-- fast HDLC inter-frame flag sequence == 1 flag byte -->
<!-- fast HDLC end flag sequence == 10 flag bytes -->
<!-- STAIRSTEP image is 1728x1728 pixels. Its is about 15k, so an average of 68.2 bits per row. To
cook it as a 31k page requires a min_bits of 141. To cook it as a 63k page requires a min_bits of
286. To cook it as a 64k page requires a min_bits of 291 -->
</messages>
<test-group name="Supplementary">
<test name="PPS-MPS-lost-PPS">
<!-- Tester calls DUT and sends one 31k byte STAIRSTEP page and one 15k byte STAIRSTEP page. -->
<step type="CALL"/>
<!--<step dir="T" type="CNG"/>-->
<step dir="R" type="CED"/>
<step dir="R" type="HDLC" modem="V.21" tag="DIS" value="FF C8 01 ..." timeout="60000"/>
<step dir="R" type="SILENCE"/>
<step type="WAIT" value="75"/>
<step dir="T" type="PREAMBLE" modem="V.21"/>
<step dir="T" type="HDLC" tag="DCS" value="FF C8 41 00 50 1F 30"/>
<step dir="T" type="POSTAMBLE"/>
<step type="WAIT" value="75"/>
<step dir="T" type="TCF" modem="V.27ter/4800" value="900"/>
<step dir="R" type="HDLC" modem="V.21" tag="CFR" value="FF C8 21"/>
<step dir="R" type="SILENCE"/>
<step type="WAIT" value="75"/>
<step dir="T" type="PREAMBLE" modem="V.27ter/4800"/>
<step dir="T" type="PP" value="etsi_300_242_a4_stairstep.tif" min_bits="141"/>
<step dir="T" type="POSTAMBLE"/>
<step type="WAIT" value="75"/>
<step dir="T" type="PREAMBLE" modem="V.21"/>
<step dir="T" type="HDLC" tag="PPS-NULL" value="FF C8 7D 00 00 00 08"/>
<step dir="T" type="POSTAMBLE"/>
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
<step dir="R" type="SILENCE"/>
<step type="WAIT" value="75"/>
<step dir="T" type="PREAMBLE" modem="V.27ter/4800"/>
<step dir="T" type="PP" value="etsi_300_242_a4_stairstep.tif"/>
<step dir="T" type="POSTAMBLE"/>
<step type="WAIT" value="75"/>
<step dir="T" type="PREAMBLE" modem="V.21"/>
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 00 80 08"/>
<step dir="T" type="POSTAMBLE"/>
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
<step dir="R" type="SILENCE"/>
<!-- Repeat the last chunk, as though we missed the MCF -->
<step type="WAIT" value="75"/>
<step dir="T" type="PREAMBLE" modem="V.27ter/4800"/>
<step dir="T" type="PP" value="etsi_300_242_a4_stairstep.tif"/>
<step dir="T" type="POSTAMBLE"/>
<step type="WAIT" value="75"/>
<step dir="T" type="PREAMBLE" modem="V.21"/>
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 00 80 08"/>
<step dir="T" type="POSTAMBLE"/>
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
<step dir="R" type="SILENCE"/>
<step type="WAIT" value="75"/>
<step dir="T" type="PREAMBLE" modem="V.27ter/4800"/>
<step dir="T" type="PP" value="etsi_300_242_a4_white.tif"/>
<step dir="T" type="POSTAMBLE"/>
<step type="WAIT" value="75"/>
<step dir="T" type="PREAMBLE" modem="V.21"/>
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 80 00 08"/>
<step dir="T" type="POSTAMBLE"/>
<step dir="R" type="HDLC" modem="V.21" tag="MCF" value="FF C8 31"/>
<step dir="R" type="SILENCE"/>
<step type="WAIT" value="75"/>
<step dir="T" type="PREAMBLE" modem="V.21"/>
<step dir="T" type="HDLC" tag="DCN" value="FF C8 5F"/>
<step dir="T" type="POSTAMBLE"/>
</test>
</test-group>
</fax-tests>

View File

@ -365,6 +365,7 @@
<step freq="525" level="-12" length="0.1"/>
<step length="0.1"/>
</offering-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Austria" uncode="at">
<dial-tone>
@ -444,6 +445,7 @@
<step freq="380+420" level="-12" length="0.4"/>
<step length="0.4"/>
</negative-indication-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Bahamas" uncode="bs">
<ringback-tone>
@ -596,6 +598,7 @@
<step freq="1380" level="-12" length="0.333"/>
<step freq="1860" level="-12" length="0.333"/>
</special-information-tone>
<!-- Billing signal: 16kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Benin" uncode="bj">
<ringback-tone>
@ -1080,6 +1083,7 @@
<step freq="440" level="-12" length="0.05"/>
<step length="0.05"/>
</route-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Canada" uncode="ca">
<dial-tone>
@ -1201,6 +1205,7 @@
<step freq="12000" level="-12" length="0.15"/>
<step length="0.15"/>
</pay-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Channel Islands: Jersey" uncode="??">
<dial-tone>
@ -1647,6 +1652,7 @@
<step freq="425" level="-12" length="0.333"/>
<step length="1.5"/>
</offering-tone>
<!-- Billing signal: 16kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Denmark" uncode="dk">
<dial-tone>
@ -1700,6 +1706,7 @@
<step freq="1400+950" level="-12" length="0.2"/>
<step length="2.0"/>
</payphone-recognition-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Diego Garcia" uncode="??">
<dial-tone>
@ -1967,6 +1974,7 @@
<step freq="1800" level="-12" length="0.33"/>
<step length="0.3"/>
</waiting-tone>
<!-- Billing signal: 16kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Ethiopia" uncode="et">
<dial-tone>
@ -2181,6 +2189,7 @@
<step freq="425" level="-12" length="0.15"/>
<step length="8.0"/>
</waiting-tone>
<!-- Billing signal: 16kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="France" uncode="fr">
<dial-tone>
@ -2210,6 +2219,7 @@
<step freq="440" level="-12" length="0.05"/>
<step length="0.05"/>
</route-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="French Polynesia" uncode="pf">
<dial-tone>
@ -2419,6 +2429,7 @@
<step length="2.0"/>
</step>
</payphone-recognition-tone>
<!-- Billing signal: 16kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Ghana" uncode="gh">
<dial-tone>
@ -2571,6 +2582,7 @@
<step freq="450" level="-12"/>
</step>
</number-unobtainable-tone>
<!-- Billing signal: 16kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Greenland" uncode="gl">
<dial-tone>
@ -3136,6 +3148,7 @@
<step freq="750+1450" level="-12" length="0.2"/>
<step length="2.0"/>
</payphone-recognition-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Israel" uncode="il">
<dial-tone>
@ -3227,6 +3240,7 @@
<step freq="400" level="-12" length="0.05"/>
<step length="2.0"/>
</holding-tone>
<!-- Billing signal: 16kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Italy" uncode="it">
<dial-tone>
@ -3247,6 +3261,7 @@
<step length="0.2"/>
</step>
</busy-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Ivory Coast" uncode="ci">
<dial-tone>
@ -3268,6 +3283,7 @@
<step freq="425" level="-12" length="0.05"/>
<step length="0.05"/>
</route-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Jamaica" uncode="jm">
<dial-tone>
@ -4181,6 +4197,7 @@
<step freq="400" level="-12" length="0.15"/>
<step length="0.15"/>
</pay-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Martinique (French Dep.)" uncode="mq">
<dial-tone>
@ -4622,6 +4639,7 @@
<step freq="425 || 450" level="-12" length="0.0625"/>
<step length="0.0625"/>
</negative-indication-tone>
<!-- Billing signal: 50Hz/~50Vrms, longitudinal/~160ms -->
</tone-set>
<tone-set country="New Caledonia" uncode="nc">
<dial-tone>
@ -4858,6 +4876,7 @@
<step length="2.0"/>
</step>
</payphone-recognition-tone>
<!-- Billing signal: 16kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Oman" uncode="om">
<dial-tone>
@ -5248,6 +5267,7 @@
<step freq="941" level="-12" length="0.2"/>
<step length="2.0"/>
</payphone-recognition-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Puerto Rico" uncode="pr">
<payphone-recognition-tone>
@ -5412,6 +5432,7 @@
<step freq="440" level="-12" length="0.05"/>
<step length="0.05"/>
</route-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="St. Helena" uncode="sh">
<dial-tone>
@ -5902,6 +5923,7 @@
<warning-tone type="conference">
<step freq="425" level="-12" length="0.66"/>
</warning-tone>
<!-- Billing signal: 16kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Slovenia" uncode="si">
<dial-tone>
@ -6144,6 +6166,7 @@
<step freq="1600" level="-12" length="0.05"/>
<step length="1.5"/>
</payphone-recognition-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Sri Lanka" uncode="lk">
<dial-tone>
@ -6357,6 +6380,7 @@
<step length="3.6"/>
</step>
</pay-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Switzerland" uncode="ch">
<dial-tone>
@ -6417,6 +6441,7 @@
<step freq="750+1450" level="-12" length="0.2"/>
<step length="2.0"/>
</payphone-recognition-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Syria" uncode="sy">
<dial-tone>
@ -6634,6 +6659,7 @@
<step length="0.167"/>
</step>
</congestion-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Turkey" uncode="tr">
<dial-tone>
@ -6701,6 +6727,7 @@
<step freq="450" level="-12" length="0.04"/>
<step length="0.04"/>
</confirmation-tone>
<!-- Billing signal: 12kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Turkmenistan" uncode="tm">
<dial-tone>
@ -6907,6 +6934,7 @@
<step length="0.125"/>
</step>
</pay-tone>
<!-- Billing signal: 50Hz/~50Vrms, longitudinal/~160ms -->
</tone-set>
<tone-set country="United States" uncode="us">
<dial-tone>
@ -7246,6 +7274,7 @@
<step freq="1800" level="-12" length="0.333"/>
<step length="1.0"/>
</special-information-tone>
<!-- Billing signal: 16kHz/~2Vrms, differential/~125ms -->
</tone-set>
<tone-set country="Zambia" uncode="zm">
<dial-tone>

View File

@ -1,7 +1,6 @@
<?xml version="1.0"?>
<!DOCTYPE fax-tests SYSTEM "./fax-tests.dtd">
<fax-tests>
<!-- $Id: tsb85.xml,v 1.22 2009/05/24 07:18:36 steveu Exp $ -->
<config>
<path type="IMAGE" value="../test-data/etsi/fax"/>
</config>
@ -1270,7 +1269,7 @@
<step dir="T" type="POSTAMBLE"/>
<step type="WAIT" value="75"/>
<step dir="T" type="PREAMBLE" modem="V.21"/>
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 00 00 08"/>
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 00 80 08"/>
<step dir="T" type="POSTAMBLE"/>
<possible-step>
@ -1292,7 +1291,7 @@
<step dir="T" type="POSTAMBLE"/>
<step type="WAIT" value="75"/>
<step dir="T" type="PREAMBLE" modem="V.21"/>
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 00 00 08"/>
<step dir="T" type="HDLC" tag="PPS-MPS" value="FF C8 7D 72 80 00 08"/>
<step dir="T" type="POSTAMBLE"/>
<possible-step>

View File

@ -15,8 +15,6 @@
## You should have received a copy of the GNU Lesser General Public
## License along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##
## $Id: Makefile.am,v 1.138.4.3 2009/12/19 10:30:10 steveu Exp $
AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
@ -56,8 +54,8 @@ EXTRA_DIST = floating_fudge.h \
libtiff.2005.vcproj \
libtiff.2008.vcproj \
filter_tools.c \
make_at_dictionary.c \
make_modem_filter.c \
make_at_dictionary.c \
make_modem_filter.c \
msvc/config.h \
msvc/Download_TIFF.2005.vcproj \
msvc/Download_TIFF.2008.vcproj \
@ -118,6 +116,7 @@ libspandsp_la_SOURCES = adsi.c \
gsm0610_short_term.c \
hdlc.c \
ima_adpcm.c \
image_translate.c \
logging.c \
lpc10_analyse.c \
lpc10_decode.c \
@ -151,6 +150,7 @@ libspandsp_la_SOURCES = adsi.c \
t38_terminal.c \
testcpuid.c \
time_scale.c \
timezone.c \
tone_detect.c \
tone_generate.c \
v17rx.c \
@ -201,6 +201,7 @@ nobase_include_HEADERS = spandsp/adsi.h \
spandsp/gsm0610.h \
spandsp/hdlc.h \
spandsp/ima_adpcm.h \
spandsp/image_translate.h \
spandsp/logging.h \
spandsp/lpc10.h \
spandsp/modem_echo.h \
@ -218,8 +219,6 @@ nobase_include_HEADERS = spandsp/adsi.h \
spandsp/super_tone_rx.h \
spandsp/super_tone_tx.h \
spandsp/swept_tone.h \
spandsp/t4_rx.h \
spandsp/t4_tx.h \
spandsp/t30.h \
spandsp/t30_api.h \
spandsp/t30_fcf.h \
@ -230,8 +229,13 @@ nobase_include_HEADERS = spandsp/adsi.h \
spandsp/t38_gateway.h \
spandsp/t38_non_ecm_buffer.h \
spandsp/t38_terminal.h \
spandsp/t4_rx.h \
spandsp/t4_tx.h \
spandsp/t4_t6_decode.h \
spandsp/t4_t6_encode.h \
spandsp/telephony.h \
spandsp/time_scale.h \
spandsp/timezone.h \
spandsp/timing.h \
spandsp/tone_detect.h \
spandsp/tone_generate.h \
@ -267,6 +271,7 @@ nobase_include_HEADERS = spandsp/adsi.h \
spandsp/private/gsm0610.h \
spandsp/private/hdlc.h \
spandsp/private/ima_adpcm.h \
spandsp/private/image_translate.h \
spandsp/private/logging.h \
spandsp/private/lpc10.h \
spandsp/private/modem_connect_tones.h \
@ -289,7 +294,10 @@ nobase_include_HEADERS = spandsp/adsi.h \
spandsp/private/t38_terminal.h \
spandsp/private/t4_rx.h \
spandsp/private/t4_tx.h \
spandsp/private/t4_t6_decode.h \
spandsp/private/t4_t6_encode.h \
spandsp/private/time_scale.h \
spandsp/private/timezone.h \
spandsp/private/tone_detect.h \
spandsp/private/tone_generate.h \
spandsp/private/v17rx.h \
@ -307,16 +315,16 @@ nobase_include_HEADERS = spandsp/adsi.h \
nodist_include_HEADERS = spandsp.h
noinst_HEADERS = faxfont.h \
filter_tools.h \
gsm0610_local.h \
lpc10_encdecs.h \
mmx_sse_decs.h \
t30_local.h \
t4_t6_decode_states.h \
v17_v32bis_rx_constellation_maps.h \
v17_v32bis_tx_constellation_maps.h \
v29tx_constellation_maps.h
noinst_HEADERS = faxfont.h \
filter_tools.h \
gsm0610_local.h \
lpc10_encdecs.h \
mmx_sse_decs.h \
t30_local.h \
t4_t6_decode_states.h \
v17_v32bis_rx_constellation_maps.h \
v17_v32bis_tx_constellation_maps.h \
v29tx_constellation_maps.h
make_at_dictionary$(EXEEXT): $(top_srcdir)/src/make_at_dictionary.c
$(CC_FOR_BUILD) -o make_at_dictionary$(EXEEXT) $(top_srcdir)/src/make_at_dictionary.c -DHAVE_CONFIG_H -I$(top_builddir)/src
@ -334,13 +342,16 @@ at_interpreter.lo: at_interpreter_dictionary.h
at_interpreter_dictionary.h: make_at_dictionary$(EXEEXT)
./make_at_dictionary$(EXEEXT) >at_interpreter_dictionary.h
t4.$(OBJEXT): spandsp/version.h
t4_rx.$(OBJEXT): spandsp/version.h
t4.lo: spandsp/version.h
t4_rx.lo: spandsp/version.h
v17rx.$(OBJEXT): v17_v32bis_rx_fixed_rrc.h v17_v32bis_rx_floating_rrc.h
V17_V32BIS_RX_INCL = v17_v32bis_rx_fixed_rrc.h \
v17_v32bis_rx_floating_rrc.h
v17rx.lo: v17_v32bis_rx_fixed_rrc.h v17_v32bis_rx_floating_rrc.h
v17rx.$(OBJEXT): ${V17_V32BIS_RX_INCL}
v17rx.lo: ${V17_V32BIS_RX_INCL}
v17_v32bis_rx_fixed_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.17 -i -r >v17_v32bis_rx_fixed_rrc.h
@ -348,9 +359,12 @@ v17_v32bis_rx_fixed_rrc.h: make_modem_filter$(EXEEXT)
v17_v32bis_rx_floating_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.17 -r >v17_v32bis_rx_floating_rrc.h
v17tx.$(OBJEXT): v17_v32bis_tx_fixed_rrc.h v17_v32bis_tx_floating_rrc.h
V17_V32BIS_TX_INCL = v17_v32bis_tx_fixed_rrc.h \
v17_v32bis_tx_floating_rrc.h
v17tx.lo: v17_v32bis_tx_fixed_rrc.h v17_v32bis_tx_floating_rrc.h
v17tx.$(OBJEXT): ${V17_V32BIS_TX_INCL}
v17tx.lo: ${V17_V32BIS_TX_INCL}
v17_v32bis_tx_fixed_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.17 -i -t >v17_v32bis_tx_fixed_rrc.h
@ -358,15 +372,14 @@ v17_v32bis_tx_fixed_rrc.h: make_modem_filter$(EXEEXT)
v17_v32bis_tx_floating_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.17 -t >v17_v32bis_tx_floating_rrc.h
v22bis_rx.$(OBJEXT): v22bis_rx_1200_fixed_rrc.h \
v22bis_rx_2400_fixed_rrc.h \
v22bis_rx_1200_floating_rrc.h \
v22bis_rx_2400_floating_rrc.h
V22BIS_RX_INCL = v22bis_rx_1200_fixed_rrc.h \
v22bis_rx_2400_fixed_rrc.h \
v22bis_rx_1200_floating_rrc.h \
v22bis_rx_2400_floating_rrc.h
v22bis_rx.lo: v22bis_rx_1200_fixed_rrc.h \
v22bis_rx_2400_fixed_rrc.h \
v22bis_rx_1200_floating_rrc.h \
v22bis_rx_2400_floating_rrc.h
v22bis_rx.$(OBJEXT): ${V22BIS_RX_INCL}
v22bis_rx.lo: ${V22BIS_RX_INCL}
v22bis_rx_1200_fixed_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.22bis1200 -i -r >v22bis_rx_1200_fixed_rrc.h
@ -380,9 +393,12 @@ v22bis_rx_1200_floating_rrc.h: make_modem_filter$(EXEEXT)
v22bis_rx_2400_floating_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.22bis2400 -r >v22bis_rx_2400_floating_rrc.h
v22bis_tx.$(OBJEXT): v22bis_tx_fixed_rrc.h v22bis_tx_floating_rrc.h
V22BIS_TX_INCL = v22bis_tx_fixed_rrc.h \
v22bis_tx_floating_rrc.h
v22bis_tx.lo: v22bis_tx_fixed_rrc.h v22bis_tx_floating_rrc.h
v22bis_tx.$(OBJEXT): ${V22BIS_TX_INCL}
v22bis_tx.lo: ${V22BIS_TX_INCL}
v22bis_tx_fixed_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.22bis -i -t >v22bis_tx_fixed_rrc.h
@ -390,16 +406,15 @@ v22bis_tx_fixed_rrc.h: make_modem_filter$(EXEEXT)
v22bis_tx_floating_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.22bis -t >v22bis_tx_floating_rrc.h
v27ter_rx_.$(OBJEXT): v27ter_rx_2400_fixed_rrc.h \
v27ter_rx_4800_fixed_rrc.h \
v27ter_rx_2400_floating_rrc.h \
v27ter_rx_4800_floating_rrc.h
v27ter_rx.lo: v27ter_rx_2400_fixed_rrc.h \
V27_RX_INCL = v27ter_rx_2400_fixed_rrc.h \
v27ter_rx_4800_fixed_rrc.h \
v27ter_rx_2400_floating_rrc.h \
v27ter_rx_4800_floating_rrc.h
v27ter_rx.$(OBJEXT): ${V27_RX_INCL}
v27ter_rx.lo: ${V27_RX_INCL}
v27ter_rx_2400_fixed_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.27ter2400 -i -r >v27ter_rx_2400_fixed_rrc.h
@ -412,15 +427,14 @@ v27ter_rx_2400_floating_rrc.h: make_modem_filter$(EXEEXT)
v27ter_rx_4800_floating_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.27ter4800 -r >v27ter_rx_4800_floating_rrc.h
v27ter_tx_.$(OBJEXT): v27ter_tx_2400_fixed_rrc.h \
v27ter_tx_4800_fixed_rrc.h \
v27ter_tx_2400_floating_rrc.h \
v27ter_tx_4800_floating_rrc.h
V27TER_TX_INCL = v27ter_tx_2400_fixed_rrc.h \
v27ter_tx_4800_fixed_rrc.h \
v27ter_tx_2400_floating_rrc.h \
v27ter_tx_4800_floating_rrc.h
v27ter_tx.lo: v27ter_tx_2400_fixed_rrc.h \
v27ter_tx_4800_fixed_rrc.h \
v27ter_tx_2400_floating_rrc.h \
v27ter_tx_4800_floating_rrc.h
v27ter_tx_.$(OBJEXT): ${V27TER_TX_INCL}
v27ter_tx.lo: ${V27TER_TX_INCL}
v27ter_tx_2400_fixed_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.27ter2400 -i -t >v27ter_tx_2400_fixed_rrc.h
@ -434,9 +448,12 @@ v27ter_tx_2400_floating_rrc.h: make_modem_filter$(EXEEXT)
v27ter_tx_4800_floating_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.27ter4800 -t >v27ter_tx_4800_floating_rrc.h
v29rx.$(OBJEXT): v29rx_fixed_rrc.h v29rx_floating_rrc.h
V29_RX_INCL = v29rx_fixed_rrc.h \
v29rx_floating_rrc.h
v29rx.lo: v29rx_fixed_rrc.h v29rx_floating_rrc.h
v29rx.$(OBJEXT): ${V29_RX_INCL}
v29rx.lo: ${V29_RX_INCL}
v29rx_fixed_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.29 -i -r >v29rx_fixed_rrc.h
@ -444,9 +461,12 @@ v29rx_fixed_rrc.h: make_modem_filter$(EXEEXT)
v29rx_floating_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.29 -r >v29rx_floating_rrc.h
v29tx.$(OBJEXT): v29tx_fixed_rrc.h v29tx_floating_rrc.h
V29_TX_INCL = v29tx_fixed_rrc.h \
v29tx_floating_rrc.h
v29tx.lo: v29tx_fixed_rrc.h v29tx_floating_rrc.h
v29tx.$(OBJEXT): ${V29_TX_INCL}
v29tx.lo: ${V29_TX_INCL}
v29tx_fixed_rrc.h: make_modem_filter$(EXEEXT)
./make_modem_filter$(EXEEXT) -m V.29 -i -t >v29tx_fixed_rrc.h
@ -519,11 +539,11 @@ $(srcdir)/msvc/spandsp.h: spandsp.h.in
-e "s/\@INSERT_INTTYPES_HEADER\@/#include <msvc\/inttypes.h>/" \
-e "s/\@INSERT_MATH_HEADER\@/#include <math.h>/" $(srcdir)/spandsp.h.in > $(srcdir)/msvc/spandsp.h
dist-hook: spandsp/version.h
spandsp/version.h:
mkdir -p $(@D)
NOWDATE=`date --utc +"%Y%m%d"` ; \
NOWTIME=`date --utc +"%H%M%S"` ; \
sed 's/$$SPANDSP_RELEASE_DATE/'$$NOWDATE'/;s/$$SPANDSP_RELEASE_TIME/'$$NOWTIME'/' \
<$(srcdir)/spandsp/version.h.in >$@
dist-hook: spandsp/version.h

View File

@ -22,8 +22,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: adsi.c,v 1.77 2009/11/02 13:25:20 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: async.c,v 1.19 2009/04/23 14:12:34 steveu Exp $
*/
/*! \file */

View File

@ -24,8 +24,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: at_interpreter.c,v 1.42.4.1 2009/12/23 14:18:32 steveu Exp $
*/
/*! \file */
@ -245,13 +243,21 @@ SPAN_DECLARE(void) at_call_event(at_state_t *s, int event)
}
else
{
/* FAX modem connection */
at_set_at_rx_mode(s, AT_MODE_DELIVERY);
if (s->silent_dial)
at_modem_control(s, AT_MODEM_CONTROL_RESTART, (void *) FAX_MODEM_NOCNG_TONE);
if (s->command_dial)
{
at_put_response_code(s, AT_RESPONSE_CODE_OK);
at_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
}
else
at_modem_control(s, AT_MODEM_CONTROL_RESTART, (void *) FAX_MODEM_CNG_TONE);
s->dte_is_waiting = TRUE;
{
/* FAX modem connection */
at_set_at_rx_mode(s, AT_MODE_DELIVERY);
if (s->silent_dial)
at_modem_control(s, AT_MODEM_CONTROL_RESTART, (void *) FAX_MODEM_NOCNG_TONE);
else
at_modem_control(s, AT_MODEM_CONTROL_RESTART, (void *) FAX_MODEM_CNG_TONE);
s->dte_is_waiting = TRUE;
}
}
break;
case AT_CALL_EVENT_BUSY:
@ -369,7 +375,7 @@ static int parse_num(const char **s, int max_value)
/* The spec. says no digits is valid, and should be treated as zero. */
i = 0;
while (isdigit(**s))
while (isdigit((int) **s))
{
i = i*10 + ((**s) - '0');
(*s)++;
@ -387,7 +393,7 @@ static int parse_hex_num(const char **s, int max_value)
/* The spec. says a hex value is always 2 digits, and the alpha digits are
upper case. */
i = 0;
if (isdigit(**s))
if (isdigit((int) **s))
i = **s - '0';
else if (**s >= 'A' && **s <= 'F')
i = **s - 'A';
@ -395,7 +401,7 @@ static int parse_hex_num(const char **s, int max_value)
return -1;
(*s)++;
if (isdigit(**s))
if (isdigit((int) **s))
i = (i << 4) | (**s - '0');
else if (**s >= 'A' && **s <= 'F')
i = (i << 4) | (**s - 'A');
@ -847,6 +853,7 @@ static const char *at_cmd_D(at_state_t *s, const char *t)
at_reset_call_info(s);
s->do_hangup = FALSE;
s->silent_dial = FALSE;
s->command_dial = FALSE;
t += 1;
ok = FALSE;
/* There are a numbers of options in a dial command string.
@ -855,7 +862,7 @@ static const char *at_cmd_D(at_state_t *s, const char *t)
u = num;
for ( ; (ch = *t); t++)
{
if (isdigit(ch))
if (isdigit((int) ch))
{
/* V.250 6.3.1.1 Basic digit set */
*u++ = ch;
@ -926,7 +933,7 @@ static const char *at_cmd_D(at_state_t *s, const char *t)
break;
case ';':
/* V.250 6.3.1 - Dial string terminator - make voice call and remain in command mode */
/* TODO: */
s->command_dial = TRUE;
break;
case '>':
/* GSM07.07 6.2 - Direct dialling from phone book supplementary service subscription
@ -5319,7 +5326,7 @@ static int command_search(const char *u, int len, int *matched)
{
/* The character in u we are processing... */
/* V.250 5.4.1 says upper and lower case are equivalent in commands */
index = (unsigned char) toupper(u[i]);
index = toupper((int) u[i]);
/* Is there a child node for this character? */
/* Note: First and last could have been packed into one uint16_t,
but space is not that critical, so the other packing is good

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: awgn.c,v 1.22 2009/02/10 13:06:46 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: bell_r2_mf.c,v 1.39.4.1 2009/12/23 14:23:48 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: bert.c,v 1.33 2009/04/14 16:04:53 steveu Exp $
*/
#if defined(HAVE_CONFIG_H)

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: bit_operations.c,v 1.16 2009/02/03 16:28:39 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: bitstream.c,v 1.18.4.1 2009/12/28 12:20:46 steveu Exp $
*/
/*! \file */
@ -74,15 +72,27 @@ SPAN_DECLARE(void) bitstream_put(bitstream_state_t *s, uint8_t **c, uint32_t val
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) bitstream_emit(bitstream_state_t *s, uint8_t **c)
{
uint32_t bitstream;
if (s->residue > 0)
{
bitstream = s->bitstream & ((1 << s->residue) - 1);
if (s->lsb_first)
*(*c) = (uint8_t) bitstream;
else
*(*c) = (uint8_t) (bitstream << (8 - s->residue));
}
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(void) bitstream_flush(bitstream_state_t *s, uint8_t **c)
{
if (s->residue > 0)
{
s->bitstream &= ((1 << s->residue) - 1);
if (s->lsb_first)
*(*c)++ = (uint8_t) s->bitstream;
else
*(*c)++ = (uint8_t) (s->bitstream << (8 - s->residue));
bitstream_emit(s, c);
(*c)++;
s->residue = 0;
}
s->bitstream = 0;

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: complex_filters.c,v 1.16 2009/02/03 16:28:39 steveu Exp $
*/
#if defined(HAVE_CONFIG_H)

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: complex_vector_float.c,v 1.16 2009/07/12 09:23:09 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: complex_vector_int.c,v 1.9 2009/07/12 09:23:09 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: crc.c,v 1.6 2009/02/03 16:28:39 steveu Exp $
*/
/*! \file */
@ -41,70 +39,38 @@
static const uint32_t crc_itu32_table[] =
{
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA,
0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988,
0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE,
0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC,
0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172,
0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940,
0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116,
0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924,
0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A,
0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818,
0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C,
0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2,
0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0,
0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086,
0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4,
0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A,
0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8,
0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE,
0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC,
0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252,
0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236,
0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04,
0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A,
0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38,
0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E,
0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C,
0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2,
0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0,
0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6,
0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
};
SPAN_DECLARE(uint32_t) crc_itu32_calc(const uint8_t *buf, int len, uint32_t crc)
@ -194,6 +160,22 @@ SPAN_DECLARE(uint16_t) crc_itu16_calc(const uint8_t *buf, int len, uint16_t crc)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(uint16_t) crc_itu16_bits(uint8_t buf, int len, uint16_t crc)
{
int i;
for (i = 0; i < len; i++)
{
if (((buf ^ crc) & 1))
crc = (crc >> 1) ^ 0x8408;
else
crc = crc >> 1;
buf >>= 1;
}
return crc;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) crc_itu16_append(uint8_t *buf, int len)
{
uint16_t crc;

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: dds_float.c,v 1.11 2009/02/03 16:28:39 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: dds_int.c,v 1.16 2009/02/21 04:27:46 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: dtmf.c,v 1.53 2009/04/12 09:12:10 steveu Exp $
*/
/*! \file */

View File

@ -26,8 +26,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: echo.c,v 1.33 2009/09/22 13:11:04 steveu Exp $
*/
/*! \file */

View File

@ -22,8 +22,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: fax.c,v 1.96.4.1 2009/12/19 10:44:10 steveu Exp $
*/
/*! \file */
@ -55,6 +53,7 @@
#include "spandsp/logging.h"
#include "spandsp/queue.h"
#include "spandsp/dc_restore.h"
#include "spandsp/vector_int.h"
#include "spandsp/power_meter.h"
#include "spandsp/complex.h"
#include "spandsp/tone_detect.h"
@ -62,17 +61,24 @@
#include "spandsp/async.h"
#include "spandsp/hdlc.h"
#include "spandsp/silence_gen.h"
#include "spandsp/super_tone_rx.h"
#include "spandsp/fsk.h"
#include "spandsp/modem_connect_tones.h"
#include "spandsp/v8.h"
#include "spandsp/v29tx.h"
#include "spandsp/v29rx.h"
#include "spandsp/v27ter_tx.h"
#include "spandsp/v27ter_rx.h"
#include "spandsp/v17tx.h"
#include "spandsp/v17rx.h"
#include "spandsp/super_tone_rx.h"
#include "spandsp/modem_connect_tones.h"
#include "spandsp/t4_rx.h"
#include "spandsp/t4_tx.h"
#if defined(SPANDSP_SUPPORT_T85)
#include "spandsp/t81_t82_arith_coding.h"
#include "spandsp/t85.h"
#endif
#include "spandsp/t4_t6_decode.h"
#include "spandsp/t4_t6_encode.h"
#include "spandsp/t30_fcf.h"
#include "spandsp/t35.h"
@ -86,15 +92,22 @@
#include "spandsp/private/logging.h"
#include "spandsp/private/silence_gen.h"
#include "spandsp/private/fsk.h"
#include "spandsp/private/modem_connect_tones.h"
#include "spandsp/private/v8.h"
#include "spandsp/private/v17tx.h"
#include "spandsp/private/v17rx.h"
#include "spandsp/private/v27ter_tx.h"
#include "spandsp/private/v27ter_rx.h"
#include "spandsp/private/v29tx.h"
#include "spandsp/private/v29rx.h"
#include "spandsp/private/modem_connect_tones.h"
#include "spandsp/private/hdlc.h"
#include "spandsp/private/fax_modems.h"
#if defined(SPANDSP_SUPPORT_T85)
#include "spandsp/private/t81_t82_arith_coding.h"
#include "spandsp/private/t85.h"
#endif
#include "spandsp/private/t4_t6_decode.h"
#include "spandsp/private/t4_t6_encode.h"
#include "spandsp/private/t4_rx.h"
#include "spandsp/private/t4_tx.h"
#include "spandsp/private/t30.h"
@ -121,6 +134,17 @@ static void tone_detected(void *user_data, int tone, int level, int delay)
}
/*- End of function --------------------------------------------------------*/
#if 0
static void v8_handler(void *user_data, v8_parms_t *result)
{
fax_state_t *s;
s = (fax_state_t *) user_data;
span_log(&s->logging, SPAN_LOG_FLOW, "V.8 report received\n");
}
/*- End of function --------------------------------------------------------*/
#endif
static void hdlc_underflow_handler(void *user_data)
{
t30_state_t *s;
@ -284,7 +308,7 @@ static int v29_v21_rx_fillin(void *user_data, int len)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) fax_rx(fax_state_t *s, int16_t *amp, int len)
SPAN_DECLARE_NONSTD(int) fax_rx(fax_state_t *s, int16_t *amp, int len)
{
int i;
@ -300,7 +324,7 @@ SPAN_DECLARE(int) fax_rx(fax_state_t *s, int16_t *amp, int len)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) fax_rx_fillin(fax_state_t *s, int len)
SPAN_DECLARE_NONSTD(int) fax_rx_fillin(fax_state_t *s, int len)
{
/* To mitigate the effect of lost packets on a packet network we should
try to sustain the status quo. If there is no receive modem running, keep
@ -348,7 +372,7 @@ static int set_next_tx_type(fax_state_t *s)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) fax_tx(fax_state_t *s, int16_t *amp, int max_len)
SPAN_DECLARE_NONSTD(int) fax_tx(fax_state_t *s, int16_t *amp, int max_len)
{
int len;
#if defined(LOG_FAX_AUDIO)
@ -577,33 +601,32 @@ SPAN_DECLARE(logging_state_t *) fax_get_logging_state(fax_state_t *s)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party)
SPAN_DECLARE(int) fax_restart(fax_state_t *s, int calling_party)
{
if (s == NULL)
{
if ((s = (fax_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
memset(s, 0, sizeof(*s));
span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
span_log_set_protocol(&s->logging, "FAX");
fax_modems_init(&s->modems,
FALSE,
t30_hdlc_accept,
hdlc_underflow_handler,
t30_non_ecm_put_bit,
t30_non_ecm_get_bit,
tone_detected,
&s->t30);
t30_init(&s->t30,
calling_party,
fax_set_rx_type,
(void *) s,
fax_set_tx_type,
(void *) s,
fax_send_hdlc,
(void *) s);
t30_set_supported_modems(&s->t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17);
#if 0
v8_parms_t v8_parms;
#endif
fax_modems_restart(&s->modems);
#if 0
v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
v8_parms.call_function = V8_CALL_T30_RX;
v8_parms.modulations = V8_MOD_V21;
if (s->t30.supported_modems & T30_SUPPORT_V27TER)
v8_parms.modulations |= V8_MOD_V27TER;
if (s->t30.supported_modems & T30_SUPPORT_V29)
v8_parms.modulations |= V8_MOD_V29;
if (s->t30.supported_modems & T30_SUPPORT_V17)
v8_parms.modulations |= V8_MOD_V17;
if (s->t30.supported_modems & T30_SUPPORT_V34HDX)
v8_parms.modulations |= V8_MOD_V34HDX;
v8_parms.protocol = V8_PROTOCOL_NONE;
v8_parms.pcm_modem_availability = 0;
v8_parms.pstn_access = 0;
v8_parms.nsf = -1;
v8_parms.t66 = -1;
v8_restart(&s->v8, calling_party, &v8_parms);
#endif
t30_restart(&s->t30);
#if defined(LOG_FAX_AUDIO)
{
@ -635,6 +658,61 @@ SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party)
s->modems.audio_tx_log = open(buf, O_CREAT | O_TRUNC | O_WRONLY, 0666);
}
#endif
return 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(fax_state_t *) fax_init(fax_state_t *s, int calling_party)
{
#if 0
v8_parms_t v8_parms;
#endif
if (s == NULL)
{
if ((s = (fax_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
memset(s, 0, sizeof(*s));
span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
span_log_set_protocol(&s->logging, "FAX");
fax_modems_init(&s->modems,
FALSE,
t30_hdlc_accept,
hdlc_underflow_handler,
t30_non_ecm_put_bit,
t30_non_ecm_get_bit,
tone_detected,
&s->t30);
t30_init(&s->t30,
calling_party,
fax_set_rx_type,
(void *) s,
fax_set_tx_type,
(void *) s,
fax_send_hdlc,
(void *) s);
t30_set_supported_modems(&s->t30, T30_SUPPORT_V27TER | T30_SUPPORT_V29 | T30_SUPPORT_V17);
#if 0
v8_parms.modem_connect_tone = MODEM_CONNECT_TONES_ANSAM_PR;
v8_parms.call_function = V8_CALL_T30_RX;
v8_parms.modulations = V8_MOD_V21;
if (s->t30.supported_modems & T30_SUPPORT_V27TER)
v8_parms.modulations |= V8_MOD_V27TER;
if (s->t30.supported_modems & T30_SUPPORT_V29)
v8_parms.modulations |= V8_MOD_V29;
if (s->t30.supported_modems & T30_SUPPORT_V17)
v8_parms.modulations |= V8_MOD_V17;
if (s->t30.supported_modems & T30_SUPPORT_V34HDX)
v8_parms.modulations |= V8_MOD_V34HDX;
v8_parms.protocol = V8_PROTOCOL_NONE;
v8_parms.pcm_modem_availability = 0;
v8_parms.pstn_access = 0;
v8_parms.nsf = -1;
v8_parms.t66 = -1;
v8_init(&s->v8, calling_party, &v8_parms, v8_handler, s);
#endif
fax_restart(s, calling_party);
return s;
}
/*- End of function --------------------------------------------------------*/

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: fax_modems.c,v 1.8 2009/11/02 13:25:20 steveu Exp $
*/
/*! \file */
@ -88,7 +86,7 @@
#define HDLC_FRAMING_OK_THRESHOLD 5
SPAN_DECLARE(int) fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], int len)
SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], int len)
{
fax_modems_state_t *s;
@ -108,7 +106,7 @@ SPAN_DECLARE(int) fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], in
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) fax_modems_v17_v21_rx_fillin(void *user_data, int len)
SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx_fillin(void *user_data, int len)
{
fax_modems_state_t *s;
@ -119,7 +117,7 @@ SPAN_DECLARE(int) fax_modems_v17_v21_rx_fillin(void *user_data, int len)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
{
fax_modems_state_t *s;
@ -139,7 +137,7 @@ SPAN_DECLARE(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[],
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int len)
SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int len)
{
fax_modems_state_t *s;
@ -150,7 +148,7 @@ SPAN_DECLARE(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int len)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], int len)
SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], int len)
{
fax_modems_state_t *s;
@ -170,7 +168,7 @@ SPAN_DECLARE(int) fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], in
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) fax_modems_v29_v21_rx_fillin(void *user_data, int len)
SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx_fillin(void *user_data, int len)
{
fax_modems_state_t *s;
@ -264,6 +262,12 @@ SPAN_DECLARE(void) fax_modems_set_tep_mode(fax_modems_state_t *s, int use_tep)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) fax_modems_restart(fax_modems_state_t *s)
{
return 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s,
int use_tep,
hdlc_frame_handler_t hdlc_accept,

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: faxfont.h,v 1.6 2008/04/17 14:26:56 steveu Exp $
*/
#if !defined(_FAXFONT_H_)

View File

@ -24,8 +24,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: filter_tools.c,v 1.11 2009/10/05 16:33:25 steveu Exp $
*/
#if defined(HAVE_CONFIG_H)

View File

@ -25,8 +25,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: filter_tools.h,v 1.3 2008/04/17 14:26:56 steveu Exp $
*/
#if !defined(_FILTER_TOOLS_H_)

View File

@ -24,8 +24,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: floating_fudge.h,v 1.7 2009/02/03 16:28:39 steveu Exp $
*/
#if !defined(_FLOATING_FUDGE_H_)

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: fsk.c,v 1.60 2009/11/02 13:25:20 steveu Exp $
*/
/*! \file */
@ -566,7 +564,7 @@ SPAN_DECLARE_NONSTD(int) fsk_rx(fsk_rx_state_t *s, const int16_t *amp, int len)
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) fsk_rx_fillin(fsk_rx_state_t *s, int len)
SPAN_DECLARE_NONSTD(int) fsk_rx_fillin(fsk_rx_state_t *s, int len)
{
/* The valid choice here is probably to do nothing. We don't change state
(i.e carrier on<->carrier off), and we'll just output less bits than we

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: g711.c,v 1.16 2009/02/10 13:06:46 steveu Exp $
*/
/*! \file */

View File

@ -27,8 +27,6 @@
* Copyright (c) CMU 1993
* Computer Science, Speech Group
* Chengxiang Lu and Alex Hauptmann
*
* $Id: g722.c,v 1.10 2009/04/22 12:57:40 steveu Exp $
*/
/*! \file */

View File

@ -47,8 +47,6 @@
* Sun Microsystems, Inc.
* 2550 Garcia Avenue
* Mountain View, California 94043
*
* $Id: g726.c,v 1.28.4.1 2009/12/28 12:20:46 steveu Exp $
*/
/*! \file */

View File

@ -24,8 +24,6 @@
*
* This code is based on the widely used GSM 06.10 code available from
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
*
* $Id: gsm0610_decode.c,v 1.25 2009/02/03 16:28:39 steveu Exp $
*/
/*! \file */

View File

@ -24,8 +24,6 @@
*
* This code is based on the widely used GSM 06.10 code available from
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
*
* $Id: gsm0610_encode.c,v 1.30 2009/02/10 13:06:46 steveu Exp $
*/
/*! \file */

View File

@ -24,8 +24,6 @@
*
* This code is based on the widely used GSM 06.10 code available from
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
*
* $Id: gsm0610_local.h,v 1.15 2009/03/13 15:57:29 steveu Exp $
*/
#if !defined(_GSM0610_LOCAL_H_)

View File

@ -24,8 +24,6 @@
*
* This code is based on the widely used GSM 06.10 code available from
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
*
* $Id: gsm0610_long_term.c,v 1.24 2009/04/20 16:36:36 steveu Exp $
*/
/*! \file */

View File

@ -24,8 +24,6 @@
*
* This code is based on the widely used GSM 06.10 code available from
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
*
* $Id: gsm0610_lpc.c,v 1.29 2009/02/05 15:57:27 steveu Exp $
*/
/*! \file */

View File

@ -24,8 +24,6 @@
*
* This code is based on the widely used GSM 06.10 code available from
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
*
* $Id: gsm0610_preprocess.c,v 1.17 2009/02/03 16:28:39 steveu Exp $
*/
/*! \file */

View File

@ -24,8 +24,6 @@
*
* This code is based on the widely used GSM 06.10 code available from
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
*
* $Id: gsm0610_rpe.c,v 1.25.4.2 2009/12/28 11:54:58 steveu Exp $
*/
/*! \file */
@ -172,7 +170,7 @@ static void weighting_filter(int16_t x[40],
: "eax", "edx", "esi", "memory"
);
#else
int32_t L_result;
int32_t result;
int k;
/* The coefficients of the weighting filter are stored in a table
@ -194,12 +192,12 @@ static void weighting_filter(int16_t x[40],
/* Compute the signal x[0..39] */
for (k = 0; k < 40; k++)
{
L_result = 8192 >> 1;
result = 8192 >> 1;
/* for (i = 0; i <= 10; i++)
* {
* L_temp = saturated_mul_16_32(wt[k + i], gsm_H[i]);
* L_result = saturated_add32(L_result, L_temp);
* temp = saturated_mul16_32(wt[k + i], gsm_H[i]);
* result = saturated_add32(result, temp);
* }
*/
@ -210,22 +208,22 @@ static void weighting_filter(int16_t x[40],
but I don't see an elegant way to optimize this.
Do you?
*/
L_result += STEP( 0, -134);
L_result += STEP( 1, -374);
/* += STEP( 2, 0 ); */
L_result += STEP( 3, 2054);
L_result += STEP( 4, 5741);
L_result += STEP( 5, 8192);
L_result += STEP( 6, 5741);
L_result += STEP( 7, 2054);
/* += STEP( 8, 0 ); */
L_result += STEP( 9, -374);
L_result += STEP(10, -134);
result += STEP( 0, -134);
result += STEP( 1, -374);
/* += STEP( 2, 0 ); */
result += STEP( 3, 2054);
result += STEP( 4, 5741);
result += STEP( 5, 8192);
result += STEP( 6, 5741);
result += STEP( 7, 2054);
/* += STEP( 8, 0 ); */
result += STEP( 9, -374);
result += STEP(10, -134);
/* 2 adds vs. >> 16 => 14, minus one shift to compensate for
those we lost when replacing L_MULT by '*'. */
L_result >>= 13;
x[k] = saturate(L_result);
result >>= 13;
x[k] = saturate(result);
}
/*endfor*/
#endif

View File

@ -24,8 +24,6 @@
*
* This code is based on the widely used GSM 06.10 code available from
* http://kbs.cs.tu-berlin.de/~jutta/toast.html
*
* $Id: gsm0610_short_term.c,v 1.19 2009/02/03 16:28:39 steveu Exp $
*/
/*! \file */

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: hdlc.c,v 1.72 2009/06/02 16:03:56 steveu Exp $
*/
/*! \file */

View File

@ -22,8 +22,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: ima_adpcm.c,v 1.36 2009/04/11 18:11:19 steveu Exp $
*/
/*! \file */

View File

@ -0,0 +1,466 @@
/*
* SpanDSP - a series of DSP components for telephony
*
* image_translate.c - Image translation routines for reworking colour
* and gray scale images to be bi-level images of an
* appropriate size to be FAX compatible.
*
* Written by Steve Underwood <steveu@coppice.org>
*
* Copyright (C) 2009 Steve Underwood
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2, as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/*! \file */
#if defined(HAVE_CONFIG_H)
#include "config.h"
#endif
#include <stdlib.h>
#include <inttypes.h>
#include <limits.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>
#include <memory.h>
#include <string.h>
#if defined(HAVE_TGMATH_H)
#include <tgmath.h>
#endif
#if defined(HAVE_MATH_H)
#include <math.h>
#endif
#include "floating_fudge.h"
#include <tiffio.h>
#include <assert.h>
#include "spandsp/telephony.h"
#include "spandsp/fast_convert.h"
#include "spandsp/logging.h"
#include "spandsp/saturated.h"
#include "spandsp/t4_rx.h"
#include "spandsp/t4_tx.h"
#if defined(SPANDSP_SUPPORT_T85)
#include "spandsp/t81_t82_arith_coding.h"
#include "spandsp/t85.h"
#endif
#include "spandsp/t4_t6_decode.h"
#include "spandsp/t4_t6_encode.h"
#include "spandsp/image_translate.h"
#include "spandsp/private/logging.h"
#if defined(SPANDSP_SUPPORT_T85)
#include "spandsp/private/t81_t82_arith_coding.h"
#include "spandsp/private/t85.h"
#endif
#include "spandsp/private/t4_t6_decode.h"
#include "spandsp/private/t4_t6_encode.h"
#include "spandsp/private/t4_rx.h"
#include "spandsp/private/t4_tx.h"
#include "spandsp/private/image_translate.h"
static int image_colour16_to_gray8_row(uint8_t mono[], uint16_t colour[], int pixels)
{
int i;
uint32_t gray;
for (i = 0; i < pixels; i++)
{
gray = colour[3*i]*19595 + colour[3*i + 1]*38469 + colour[3*i + 2]*7472;
mono[i] = saturateu8(gray >> 24);
}
return pixels;
}
/*- End of function --------------------------------------------------------*/
static int image_colour8_to_gray8_row(uint8_t mono[], uint8_t colour[], int pixels)
{
int i;
uint32_t gray;
for (i = 0; i < pixels; i++)
{
gray = colour[3*i]*19595 + colour[3*i + 1]*38469 + colour[3*i + 2]*7472;
mono[i] = saturateu8(gray >> 16);
}
return pixels;
}
/*- End of function --------------------------------------------------------*/
static int image_gray16_to_gray8_row(uint8_t mono[], uint16_t gray[], int pixels)
{
int i;
for (i = 0; i < pixels; i++)
mono[i] = gray[i] >> 8;
return pixels;
}
/*- End of function --------------------------------------------------------*/
static int get_and_scrunch_row(image_translate_state_t *s, uint8_t buf[], size_t len)
{
int row_len;
row_len = (*s->row_read_handler)(s->row_read_user_data, buf, s->input_width*s->bytes_per_pixel);
if (row_len != s->input_width*s->bytes_per_pixel)
return 0;
/* Scrunch colour down to gray, and scrunch 16 bit pixels down to 8 bit pixels */
switch (s->input_format)
{
case IMAGE_TRANSLATE_FROM_GRAY_16:
image_gray16_to_gray8_row(buf, (uint16_t *) buf, s->input_width);
break;
case IMAGE_TRANSLATE_FROM_COLOUR_16:
image_colour16_to_gray8_row(buf, (uint16_t *) buf, s->input_width);
break;
case IMAGE_TRANSLATE_FROM_COLOUR_8:
image_colour8_to_gray8_row(buf, buf, s->input_width);
break;
}
return row_len;
}
/*- End of function --------------------------------------------------------*/
static int image_resize_row(image_translate_state_t *s, uint8_t buf[], size_t len)
{
int i;
int output_width;
int output_length;
int input_width;
int input_length;
double c1;
double c2;
double int_part;
int x;
#if defined(SPANDSP_USE_FIXED_POINT)
int frac_row;
int frac_col;
#else
double frac_row;
double frac_col;
#endif
int row_len;
int skip;
uint8_t *p;
if (s->raw_output_row < 0)
return 0;
output_width = s->output_width - 1;
output_length = s->output_length - 1;
input_width = s->input_width - 1;
input_length = s->input_length - 1;
skip = s->raw_output_row*input_length/output_length;
if (skip >= s->raw_input_row)
{
skip++;
while (skip >= s->raw_input_row)
{
if (s->raw_input_row >= s->input_length)
{
s->raw_output_row = -1;
break;
}
row_len = get_and_scrunch_row(s, s->raw_pixel_row[0], s->input_width*s->bytes_per_pixel);
if (row_len != s->input_width*s->bytes_per_pixel)
{
s->raw_output_row = -1;
return 0;
}
s->raw_input_row++;
p = s->raw_pixel_row[0];
s->raw_pixel_row[0] = s->raw_pixel_row[1];
s->raw_pixel_row[1] = p;
}
}
#if defined(SPANDSP_USE_FIXED_POINT)
frac_row = s->raw_output_row*input_length/output_length;
frac_row = s->raw_output_row*input_length - frac_row*output_length;
for (i = 0; i < output_width; i++)
{
x = i*input_width/output_width;
frac_col = x - x*output_width;
c1 = s->raw_pixel_row[0][x] + (s->raw_pixel_row[0][x + 1] - s->raw_pixel_row[0][x])*frac_col;
c1 = s->raw_pixel_row[1][x] + (s->raw_pixel_row[1][x + 1] - s->raw_pixel_row[1][x])*frac_col;
buf[i] = saturateu8(c1 + (c2 - c1)*frac_row);
}
#else
frac_row = modf((double) s->raw_output_row*input_length/output_length, &int_part);
for (i = 0; i < output_width; i++)
{
frac_col = modf((double) i*input_width/output_width, &int_part);
x = int_part;
c1 = s->raw_pixel_row[0][x] + (s->raw_pixel_row[0][x + 1] - s->raw_pixel_row[0][x])*frac_col;
c2 = s->raw_pixel_row[1][x] + (s->raw_pixel_row[1][x + 1] - s->raw_pixel_row[1][x])*frac_col;
buf[i] = saturateu8(c1 + (c2 - c1)*frac_row);
}
#endif
if (++s->raw_output_row >= s->output_length)
s->raw_output_row = -1;
return len;
}
/*- End of function --------------------------------------------------------*/
static __inline__ uint8_t find_closest_palette_color(int in)
{
return (in >= 128) ? 255 : 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) image_translate_row(image_translate_state_t *s, uint8_t buf[], size_t len)
{
int x;
int y;
int i;
int j;
int limit;
int old_pixel;
int new_pixel;
int quant_error;
uint8_t *p;
uint8_t xx;
if (s->output_row < 0)
return 0;
y = s->output_row++;
/* This algorithm works over two rows, and outputs the earlier of the two. To
make this work:
- At row 0 we grab and scrunch two rows.
- From row 1 up to the last row we grab one new additional row each time.
- At the last row we dither and output, without getting an extra row in. */
for (i = (y == 0) ? 0 : 1; i < 2; i++)
{
p = s->pixel_row[0];
s->pixel_row[0] = s->pixel_row[1];
s->pixel_row[1] = p;
/* If this is the end of the image just ignore that there is now rubbish in pixel_row[1].
Mark that the end has occurred. This row will be properly output, and the next one
will fail, with the end of image condition (i.e. returning zero length) */
if (s->resize)
{
if (image_resize_row(s, s->pixel_row[1], s->output_width*s->bytes_per_pixel) != s->output_width*s->bytes_per_pixel)
s->output_row = -1;
}
else
{
if (get_and_scrunch_row(s, s->pixel_row[1], s->output_width*s->bytes_per_pixel) != s->output_width*s->bytes_per_pixel)
s->output_row = -1;
}
}
/* Apply Floyd-Steinberg dithering to the 8 bit pixels, using a bustrophodontic
scan, to reduce the grayscale image to pure black and white */
/* The first and last pixels in each row need special treatment, so we do not
step outside the row. */
if ((y & 1))
{
x = s->output_width - 1;
old_pixel = s->pixel_row[0][x];
new_pixel = find_closest_palette_color(old_pixel);
quant_error = old_pixel - new_pixel;
s->pixel_row[0][x + 0] = new_pixel;
s->pixel_row[0][x - 1] = saturateu8(s->pixel_row[0][x - 1] + (7*quant_error)/16);
s->pixel_row[1][x + 0] = saturateu8(s->pixel_row[1][x + 0] + (5*quant_error)/16);
s->pixel_row[1][x - 1] = saturateu8(s->pixel_row[1][x - 1] + (1*quant_error)/16);
for ( ; x > 0; x--)
{
old_pixel = s->pixel_row[0][x];
new_pixel = find_closest_palette_color(old_pixel);
quant_error = old_pixel - new_pixel;
s->pixel_row[0][x + 0] = new_pixel;
s->pixel_row[0][x - 1] = saturateu8(s->pixel_row[0][x - 1] + (7*quant_error)/16);
s->pixel_row[1][x + 1] = saturateu8(s->pixel_row[1][x + 1] + (3*quant_error)/16);
s->pixel_row[1][x + 0] = saturateu8(s->pixel_row[1][x + 0] + (5*quant_error)/16);
s->pixel_row[1][x - 1] = saturateu8(s->pixel_row[1][x - 1] + (1*quant_error)/16);
}
old_pixel = s->pixel_row[0][x];
new_pixel = find_closest_palette_color(old_pixel);
quant_error = old_pixel - new_pixel;
s->pixel_row[0][x + 0] = new_pixel;
s->pixel_row[1][x + 1] = saturateu8(s->pixel_row[1][x + 1] + (3*quant_error)/16);
s->pixel_row[1][x + 0] = saturateu8(s->pixel_row[1][x + 0] + (5*quant_error)/16);
}
else
{
x = 0;
old_pixel = s->pixel_row[0][x];
new_pixel = find_closest_palette_color(old_pixel);
quant_error = old_pixel - new_pixel;
s->pixel_row[0][x + 0] = new_pixel;
s->pixel_row[0][x + 1] = saturateu8(s->pixel_row[0][x + 1] + (7*quant_error)/16);
s->pixel_row[1][x + 0] = saturateu8(s->pixel_row[1][x + 0] + (5*quant_error)/16);
s->pixel_row[1][x + 1] = saturateu8(s->pixel_row[1][x + 1] + (1*quant_error)/16);
for ( ; x < s->output_width - 1; x++)
{
old_pixel = s->pixel_row[0][x];
new_pixel = find_closest_palette_color(old_pixel);
quant_error = old_pixel - new_pixel;
s->pixel_row[0][x + 0] = new_pixel;
s->pixel_row[0][x + 1] = saturateu8(s->pixel_row[0][x + 1] + (7*quant_error)/16);
s->pixel_row[1][x - 1] = saturateu8(s->pixel_row[1][x - 1] + (3*quant_error)/16);
s->pixel_row[1][x + 0] = saturateu8(s->pixel_row[1][x + 0] + (5*quant_error)/16);
s->pixel_row[1][x + 1] = saturateu8(s->pixel_row[1][x + 1] + (1*quant_error)/16);
}
old_pixel = s->pixel_row[0][x];
new_pixel = find_closest_palette_color(old_pixel);
quant_error = old_pixel - new_pixel;
s->pixel_row[0][x + 0] = new_pixel;
s->pixel_row[1][x - 1] = saturateu8(s->pixel_row[1][x - 1] + (3*quant_error)/16);
s->pixel_row[1][x + 0] = saturateu8(s->pixel_row[1][x + 0] + (5*quant_error)/16);
}
/* Now bit pack the pixel per byte row into a pixel per bit row. */
for (i = 0, x = 0; x < s->output_width; i++, x += 8)
{
xx = 0;
/* Allow for the possibility that the width is not a multiple of 8 */
limit = (8 <= s->output_width - x) ? 8 : (s->output_width - x);
for (j = 0; j < limit; j++)
{
if (s->pixel_row[0][x + j] <= 128)
xx |= (1 << (7 - j));
}
buf[i] = xx;
}
return i;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) image_translate_get_output_width(image_translate_state_t *s)
{
return s->output_width;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) image_translate_get_output_length(image_translate_state_t *s)
{
return s->output_length;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(image_translate_state_t *) image_translate_init(image_translate_state_t *s,
int input_format,
int input_width,
int input_length,
int output_width,
t4_row_read_handler_t row_read_handler,
void *row_read_user_data)
{
int i;
if (s == NULL)
{
if ((s = (image_translate_state_t *) malloc(sizeof(*s))) == NULL)
return NULL;
}
memset(s, 0, sizeof(*s));
s->input_format = input_format;
s->input_width = input_width;
s->input_length = input_length;
s->resize = (output_width > 0);
s->output_width = (s->resize) ? output_width : s->input_width;
s->output_length = (s->resize) ? s->input_length*s->output_width/s->input_width : s->input_length;
switch (s->input_format)
{
case IMAGE_TRANSLATE_FROM_GRAY_8:
s->bytes_per_pixel = 1;
break;
case IMAGE_TRANSLATE_FROM_GRAY_16:
s->bytes_per_pixel = 2;
break;
case IMAGE_TRANSLATE_FROM_COLOUR_8:
s->bytes_per_pixel = 3;
break;
case IMAGE_TRANSLATE_FROM_COLOUR_16:
s->bytes_per_pixel = 6;
break;
default:
s->bytes_per_pixel = 1;
break;
}
/* Allocate the two row buffers we need, using the space requirements we now have */
if (s->resize)
{
for (i = 0; i < 2; i++)
{
if ((s->raw_pixel_row[i] = (uint8_t *) malloc(s->input_width*s->bytes_per_pixel)) == NULL)
return NULL;
memset(s->raw_pixel_row[i], 0, s->input_width*s->bytes_per_pixel);
if ((s->pixel_row[i] = (uint8_t *) malloc(s->output_width*sizeof(uint8_t))) == NULL)
return NULL;
memset(s->pixel_row[i], 0, s->output_width*sizeof(uint8_t));
}
}
else
{
for (i = 0; i < 2; i++)
{
if ((s->pixel_row[i] = (uint8_t *) malloc(s->output_width*s->bytes_per_pixel)) == NULL)
return NULL;
memset(s->pixel_row[i], 0, s->output_width*s->bytes_per_pixel);
}
}
s->row_read_handler = row_read_handler;
s->row_read_user_data = row_read_user_data;
s->raw_input_row = 0;
s->raw_output_row = 0;
s->output_row = 0;
return s;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) image_translate_release(image_translate_state_t *s)
{
int i;
for (i = 0; i < 2; i++)
{
if (s->raw_pixel_row[i])
{
free(s->raw_pixel_row[i]);
s->raw_pixel_row[i] = NULL;
}
if (s->pixel_row[i])
{
free(s->pixel_row[i]);
s->pixel_row[i] = NULL;
}
}
return 0;
}
/*- End of function --------------------------------------------------------*/
SPAN_DECLARE(int) image_translate_free(image_translate_state_t *s)
{
int res;
res = image_translate_release(s);
free(s);
return res;
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/

View File

@ -226,6 +226,7 @@
<File RelativePath="t38_terminal.c"></File>
<File RelativePath="testcpuid.c"></File>
<File RelativePath="time_scale.c"></File>
<File RelativePath="timezone.c"></File>
<File RelativePath="tone_detect.c"></File>
<File RelativePath="tone_generate.c"></File>
<File RelativePath="v17rx.c"></File>
@ -294,6 +295,8 @@
<File RelativePath="spandsp/swept_tone.h"></File>
<File RelativePath="spandsp/t4_rx.h"></File>
<File RelativePath="spandsp/t4_tx.h"></File>
<File RelativePath="spandsp/t4_t6_decode.h"></File>
<File RelativePath="spandsp/t4_t6_encode.h"></File>
<File RelativePath="spandsp/t30.h"></File>
<File RelativePath="spandsp/t30_api.h"></File>
<File RelativePath="spandsp/t30_fcf.h"></File>

View File

@ -219,6 +219,7 @@
<ClCompile Include="t38_terminal.c" />
<ClCompile Include="testcpuid.c" />
<ClCompile Include="time_scale.c" />
<ClCompile Include="timezone.c" />
<ClCompile Include="tone_detect.c" />
<ClCompile Include="tone_generate.c" />
<ClCompile Include="v17rx.c" />
@ -288,6 +289,8 @@
<ClInclude Include="spandsp\swept_tone.h" />
<ClInclude Include="spandsp\t4_rx.h" />
<ClInclude Include="spandsp\t4_tx.h" />
<ClInclude Include="spandsp\t4_t6_decode.h" />
<ClInclude Include="spandsp\t4_t6_encode.h" />
<ClInclude Include="spandsp\t30.h" />
<ClInclude Include="spandsp\t30_api.h" />
<ClInclude Include="spandsp\t30_fcf.h" />

View File

@ -21,8 +21,6 @@
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id: logging.c,v 1.32 2009/02/10 17:44:18 steveu Exp $
*/
/*! \file */

View File

@ -25,8 +25,6 @@
* This code is based on the U.S. Department of Defense reference
* implementation of the LPC-10 2400 bps Voice Coder. They do not
* exert copyright claims on their code, and it may be freely used.
*
* $Id: lpc10_analyse.c,v 1.22 2009/01/28 03:41:27 steveu Exp $
*/
#if defined(HAVE_CONFIG_H)

View File

@ -25,8 +25,6 @@
* This code is based on the U.S. Department of Defense reference
* implementation of the LPC-10 2400 bps Voice Coder. They do not
* exert copyright claims on their code, and it may be freely used.
*
* $Id: lpc10_decode.c,v 1.27.4.1 2009/12/24 17:00:19 steveu Exp $
*/
#if defined(HAVE_CONFIG_H)
@ -251,6 +249,7 @@ static int pitsyn(lpc10_decode_state_t *s,
float slope;
float uvpit;
float xxy;
float msix;
rci_dim1 = LPC10_ORDER;
rci_offset = rci_dim1 + 1;
@ -446,7 +445,10 @@ static int pitsyn(lpc10_decode_state_t *s,
xxy = expf(xxy);
rci[j + *nout*rci_dim1 + 1] = (xxy - 1.0f)/(xxy + 1.0f);
}
rmsi[*nout - 1] = expf(logf(s->rmso) + prop*(logf(*rms) - logf(s->rmso)));
msix = logf(*rms) - logf(s->rmso);
msix = prop*msix;
msix = logf(s->rmso) + msix;
rmsi[*nout - 1] = expf(msix);
}
}
if (vflag != 1)

Some files were not shown because too many files have changed in this diff Show More