2010-03-02 23:11:06 +00:00
/*
* Asterisk - - An open source telephony toolkit .
*
* Copyright ( C ) 2008 - 2009 , Digium , Inc .
*
* Dwayne M . Hubbard < dhubbard @ digium . com >
* Kevin P . Fleming < kpfleming @ digium . com >
2011-06-30 18:22:28 +00:00
* Matthew Nicholson < mnicholson @ digium . com >
*
* Initial T .38 - gateway code
* 2008 , Daniel Ferenci < daniel . ferenci @ nethemba . com >
* Created by Nethemba s . r . o . http : //www.nethemba.com
* Sponsored by IPEX a . s . http : //www.ipex.cz
*
* T .38 - gateway integration into asterisk app_fax and rework
2011-07-01 12:45:09 +00:00
* 2008 - 2011 , Gregory Hinton Nietsky < gregory @ distrotech . co . za >
2011-06-30 18:22:28 +00:00
* dns Telecom http : //www.dnstelecom.co.za
*
* Modified to make T .38 - gateway compatible with Asterisk 1.6 .2
* 2010 , Anton Verevkin < mymail @ verevkin . it >
* ViaNetTV http : //www.vianettv.com
*
* Modified to make T .38 - gateway work
* 2010 , Klaus Darilion , IPCom GmbH , www . ipcom . at
2010-03-02 23:11:06 +00:00
*
* See http : //www.asterisk.org for more information about
* the Asterisk project . Please do not directly contact
* any of the maintainers of this project for assistance ;
* the project provides a web site , mailing lists and IRC
* channels for your use .
*
* This program is free software , distributed under the terms of
* the GNU General Public License Version 2. See the LICENSE file
* at the top of the source tree .
*/
2010-03-03 15:39:45 +00:00
/*** MODULEINFO
< conflict > app_fax < / conflict >
2012-08-18 01:14:42 +00:00
< support_level > core < / support_level >
2010-03-03 15:39:45 +00:00
* * */
2010-03-02 23:11:06 +00:00
/*! \file
*
* \ brief Generic FAX Resource for FAX technology resource modules
*
* \ author Dwayne M . Hubbard < dhubbard @ digium . com >
* \ author Kevin P . Fleming < kpfleming @ digium . com >
2011-06-30 18:22:28 +00:00
* \ author Matthew Nicholson < mnicholson @ digium . com >
2011-07-01 12:45:09 +00:00
* \ author Gregory H . Nietsky < gregory @ distrotech . co . za >
2011-10-21 09:16:12 +00:00
*
2010-03-02 23:11:06 +00:00
* A generic FAX resource module that provides SendFAX and ReceiveFAX applications .
* This module requires FAX technology modules , like res_fax_spandsp , to register with it
* so it can use the technology modules to perform the actual FAX transmissions .
* \ ingroup applications
*/
2012-10-14 21:44:27 +00:00
/*! \li \ref res_fax.c uses the configuration file \ref res_fax.conf
2012-10-01 23:24:10 +00:00
* \ addtogroup configuration_file Configuration Files
*/
2013-06-22 13:58:07 +00:00
/*!
2012-10-01 23:24:10 +00:00
* \ page res_fax . conf res_fax . conf
* \ verbinclude res_fax . conf . sample
*/
2010-03-02 23:11:06 +00:00
# include "asterisk.h"
git migration: Refactor the ASTERISK_FILE_VERSION macro
Git does not support the ability to replace a token with a version
string during check-in. While it does have support for replacing a
token on clone, this is somewhat sub-optimal: the token is replaced
with the object hash, which is not particularly easy for human
consumption. What's more, in practice, the source file version was often
not terribly useful. Generally, when triaging bugs, the overall version
of Asterisk is far more useful than an individual SVN version of a file. As a
result, this patch removes Asterisk's support for showing source file
versions.
Specifically, it does the following:
* Rename ASTERISK_FILE_VERSION macro to ASTERISK_REGISTER_FILE, and
remove passing the version in with the macro. Other facilities
than 'core show file version' make use of the file names, such as
setting a debug level only on a specific file. As such, the act of
registering source files with the Asterisk core still has use. The
macro rename now reflects the new macro purpose.
* main/asterisk:
- Refactor the file_version structure to reflect that it no longer
tracks a version field.
- Remove the "core show file version" CLI command. Without the file
version, it is no longer useful.
- Remove the ast_file_version_find function. The file version is no
longer tracked.
- Rename ast_register_file_version/ast_unregister_file_version to
ast_register_file/ast_unregister_file, respectively.
* main/manager: Remove value from the Version key of the ModuleCheck
Action. The actual key itself has not been removed, as doing so would
absolutely constitute a backwards incompatible change. However, since
the file version is no longer tracked, there is no need to attempt to
include it in the Version key.
* UPGRADE: Add notes for:
- Modification to the ModuleCheck AMI Action
- Removal of the "core show file version" CLI command
Change-Id: I6cf0ff280e1668bf4957dc21f32a5ff43444a40e
2015-04-12 02:38:22 +00:00
ASTERISK_REGISTER_FILE ( )
2010-03-02 23:11:06 +00:00
# include "asterisk/io.h"
# include "asterisk/file.h"
# include "asterisk/logger.h"
# include "asterisk/module.h"
# include "asterisk/app.h"
# include "asterisk/lock.h"
# include "asterisk/options.h"
# include "asterisk/strings.h"
# include "asterisk/cli.h"
# include "asterisk/utils.h"
# include "asterisk/config.h"
# include "asterisk/astobj2.h"
2010-04-26 14:18:15 +00:00
# include "asterisk/res_fax.h"
2010-03-02 23:11:06 +00:00
# include "asterisk/file.h"
# include "asterisk/channel.h"
# include "asterisk/pbx.h"
# include "asterisk/dsp.h"
2010-04-26 14:18:15 +00:00
# include "asterisk/indications.h"
2010-06-22 16:17:14 +00:00
# include "asterisk/ast_version.h"
2011-06-30 18:22:28 +00:00
# include "asterisk/translate.h"
2013-05-24 20:44:07 +00:00
# include "asterisk/stasis.h"
# include "asterisk/stasis_channels.h"
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
# include "asterisk/smoother.h"
# include "asterisk/format_cache.h"
2010-03-02 23:11:06 +00:00
2010-07-17 00:03:37 +00:00
/*** DOCUMENTATION
2011-10-10 14:16:27 +00:00
< application name = " ReceiveFAX " language = " en_US " module = " res_fax " >
2010-07-17 00:03:37 +00:00
< synopsis >
Receive a FAX and save as a TIFF / F file .
< / synopsis >
< syntax >
< parameter name = " filename " required = " true " / >
< parameter name = " options " >
< optionlist >
< option name = " d " >
< para > Enable FAX debugging . < / para >
< / option >
< option name = " f " >
< para > Allow audio fallback FAX transfer on T .38 capable channels . < / para >
< / option >
2011-01-27 15:57:52 +00:00
< option name = " F " >
< para > Force usage of audio mode on T .38 capable channels . < / para >
2011-01-26 22:39:07 +00:00
< / option >
2010-07-17 00:03:37 +00:00
< option name = " s " >
< para > Send progress Manager events ( overrides statusevents setting in res_fax . conf ) . < / para >
< / option >
< / optionlist >
< / parameter >
< / syntax >
< description >
< para > This application is provided by res_fax , which is a FAX technology agnostic module
that utilizes FAX technology resource modules to complete a FAX transmission . < / para >
< para > Session arguments can be set by the FAXOPT function and to check results of the ReceiveFax ( ) application . < / para >
< / description >
< see - also >
< ref type = " function " > FAXOPT < / ref >
< / see - also >
< / application >
2011-10-10 14:16:27 +00:00
< application name = " SendFAX " language = " en_US " module = " res_fax " >
2010-07-17 00:03:37 +00:00
< synopsis >
Sends a specified TIFF / F file as a FAX .
< / synopsis >
< syntax >
< parameter name = " filename " required = " true " argsep = " & " >
< argument name = " filename2 " multiple = " true " >
< para > TIFF file to send as a FAX . < / para >
< / argument >
< / parameter >
< parameter name = " options " >
< optionlist >
< option name = " d " >
< para > Enable FAX debugging . < / para >
< / option >
< option name = " f " >
< para > Allow audio fallback FAX transfer on T .38 capable channels . < / para >
< / option >
2011-01-27 15:57:52 +00:00
< option name = " F " >
< para > Force usage of audio mode on T .38 capable channels . < / para >
2011-01-26 22:39:07 +00:00
< / option >
2010-07-17 00:03:37 +00:00
< option name = " s " >
< para > Send progress Manager events ( overrides statusevents setting in res_fax . conf ) . < / para >
< / option >
< option name = " z " >
< para > Initiate a T .38 reinvite on the channel if the remote end does not . < / para >
< / option >
< / optionlist >
< / parameter >
< / syntax >
< description >
< para > This application is provided by res_fax , which is a FAX technology agnostic module
that utilizes FAX technology resource modules to complete a FAX transmission . < / para >
< para > Session arguments can be set by the FAXOPT function and to check results of the SendFax ( ) application . < / para >
< / description >
< see - also >
< ref type = " function " > FAXOPT < / ref >
< / see - also >
< / application >
2011-10-10 14:16:27 +00:00
< function name = " FAXOPT " language = " en_US " module = " res_fax " >
2010-07-17 00:03:37 +00:00
< synopsis >
Gets / sets various pieces of information about a fax session .
< / synopsis >
< syntax >
< parameter name = " item " required = " true " >
< enumlist >
< enum name = " ecm " >
< para > R / W Error Correction Mode ( ECM ) enable with ' yes ' , disable with ' no ' . < / para >
< / enum >
< enum name = " error " >
< para > R / O FAX transmission error code upon failure . < / para >
< / enum >
< enum name = " filename " >
< para > R / O Filename of the first file of the FAX transmission . < / para >
< / enum >
< enum name = " filenames " >
< para > R / O Filenames of all of the files in the FAX transmission ( comma separated ) . < / para >
< / enum >
< enum name = " headerinfo " >
< para > R / W FAX header information . < / para >
< / enum >
< enum name = " localstationid " >
< para > R / W Local Station Identification . < / para >
< / enum >
< enum name = " minrate " >
< para > R / W Minimum transfer rate set before transmission . < / para >
< / enum >
< enum name = " maxrate " >
< para > R / W Maximum transfer rate set before transmission . < / para >
< / enum >
< enum name = " modem " >
< para > R / W Modem type ( v17 / v27 / v29 ) . < / para >
< / enum >
2011-06-30 18:22:28 +00:00
< enum name = " gateway " >
2011-08-30 14:03:02 +00:00
< para > R / W T38 fax gateway , with optional fax activity timeout in seconds ( yes [ , timeout ] / no ) < / para >
2011-08-22 16:31:59 +00:00
< / enum >
2011-10-05 06:50:18 +00:00
< enum name = " faxdetect " >
< para > R / W Enable FAX detect with optional timeout in seconds ( yes , t38 , cng [ , timeout ] / no ) < / para >
< / enum >
2010-07-17 00:03:37 +00:00
< enum name = " pages " >
< para > R / O Number of pages transferred . < / para >
< / enum >
< enum name = " rate " >
< para > R / O Negotiated transmission rate . < / para >
< / enum >
< enum name = " remotestationid " >
< para > R / O Remote Station Identification after transmission . < / para >
< / enum >
< enum name = " resolution " >
< para > R / O Negotiated image resolution after transmission . < / para >
< / enum >
< enum name = " sessionid " >
< para > R / O Session ID of the FAX transmission . < / para >
< / enum >
< enum name = " status " >
< para > R / O Result Status of the FAX transmission . < / para >
< / enum >
< enum name = " statusstr " >
< para > R / O Verbose Result Status of the FAX transmission . < / para >
< / enum >
2015-01-09 14:53:09 +00:00
< enum name = " t38timeout " >
< para > R / W The timeout used for T .38 negotiation . < / para >
< / enum >
2010-07-17 00:03:37 +00:00
< / enumlist >
< / parameter >
< / syntax >
< description >
< para > FAXOPT can be used to override the settings for a FAX session listed in < filename > res_fax . conf < / filename > ,
2015-01-23 15:13:08 +00:00
it can also be used to retrieve information about a FAX session that has finished eg . pages / status . < / para >
2010-07-17 00:03:37 +00:00
< / description >
< see - also >
< ref type = " application " > ReceiveFax < / ref >
< ref type = " application " > SendFax < / ref >
< / see - also >
< / function >
2014-07-18 15:49:46 +00:00
< manager name = " FAXSessions " language = " en_US " >
< synopsis >
Lists active FAX sessions
< / synopsis >
< syntax >
< xi : include xpointer = " xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID']) " / >
< / syntax >
< description >
< para > Will generate a series of FAXSession events with information about each FAXSession . Closes with
a FAXSessionsComplete event which includes a count of the included FAX sessions . This action works in
the same manner as the CLI command ' fax show sessions ' < / para >
< / description >
< / manager >
< managerEvent language = " en_US " name = " FAXSessionsEntry " >
< managerEventInstance class = " EVENT_FLAG_REPORTING " >
< synopsis > A single list item for the FAXSessions AMI command < / synopsis >
< syntax >
< parameter name = " ActionID " required = " false " / >
< parameter name = " Channel " >
< para > Name of the channel responsible for the FAX session < / para >
< / parameter >
< parameter name = " Technology " >
< para > The FAX technology that the FAX session is using < / para >
< / parameter >
< parameter name = " SessionNumber " >
< para > The numerical identifier for this particular session < / para >
< / parameter >
< parameter name = " SessionType " >
< para > FAX session passthru / relay type < / para >
< enumlist >
< enum name = " G.711 " / >
< enum name = " T.38 " / >
< / enumlist >
< / parameter >
< parameter name = " Operation " >
< para > FAX session operation type < / para >
< enumlist >
< enum name = " gateway " / >
< enum name = " V.21 " / >
< enum name = " send " / >
< enum name = " receive " / >
< enum name = " none " / >
< / enumlist >
< / parameter >
< parameter name = " State " >
< para > Current state of the FAX session < / para >
< enumlist >
< enum name = " Uninitialized " / >
< enum name = " Initialized " / >
< enum name = " Open " / >
< enum name = " Active " / >
< enum name = " Complete " / >
< enum name = " Reserved " / >
< enum name = " Inactive " / >
< enum name = " Unknown " / >
< / enumlist >
< / parameter >
< parameter name = " Files " >
< para > File or list of files associated with this FAX session < / para >
< / parameter >
< / syntax >
< / managerEventInstance >
< / managerEvent >
< managerEvent language = " en_US " name = " FAXSessionsComplete " >
< managerEventInstance class = " EVENT_FLAG_CALL " >
< synopsis > Raised when all FAXSession events are completed for a FAXSessions command < / synopsis >
< syntax >
< parameter name = " ActionID " required = " false " / >
< parameter name = " Total " >
< para > Count of FAXSession events sent in response to FAXSessions action < / para >
< / parameter >
< / syntax >
< / managerEventInstance >
< / managerEvent >
< manager name = " FAXSession " language = " en_US " >
< synopsis >
Responds with a detailed description of a single FAX session
< / synopsis >
< syntax >
< xi : include xpointer = " xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID']) " / >
< parameter name = " SessionNumber " required = " true " >
< para > The session ID of the fax the user is interested in . < / para >
< / parameter >
< / syntax >
< description >
< para > Provides details about a specific FAX session . The response will include a common subset of
the output from the CLI command ' fax show session & lt ; session_number & gt ; ' for each technology . If the
FAX technolgy used by this session does not include a handler for FAXSession , then this action
will fail . < / para >
< / description >
< / manager >
< managerEvent language = " en_US " name = " FAXSession " >
< managerEventInstance class = " EVENT_FLAG_REPORTING " >
< synopsis > Raised in response to FAXSession manager command < / synopsis >
< syntax >
< parameter name = " ActionID " required = " false " / >
< parameter name = " SessionNumber " >
< para > The numerical identifier for this particular session < / para >
< / parameter >
< xi : include xpointer = " xpointer(/docs/managerEvent[@name='FAXSessionsEntry']/managerEventInstance/syntax/parameter[@name='Operation']) " / >
< xi : include xpointer = " xpointer(/docs/managerEvent[@name='FAXSessionsEntry']/managerEventInstance/syntax/parameter[@name='State']) " / >
< parameter name = " ErrorCorrectionMode " required = " false " >
< para > Whether error correcting mode is enabled for the FAX session . This field is not
included when operation is ' V .21 Detect ' or if operation is ' gateway ' and state is
' Uninitialized '
< / para >
< enumlist >
< enum name = " yes " / >
< enum name = " no " / >
< / enumlist >
< / parameter >
< parameter name = " DataRate " required = " false " >
< para > Bit rate of the FAX . This field is not included when operation is ' V .21 Detect ' or
if operation is ' gateway ' and state is ' Uninitialized ' . < / para >
< / parameter >
< parameter name = " ImageResolution " required = " false " >
< para > Resolution of each page of the FAX . Will be in the format of X_RESxY_RES . This field
is not included if the operation is anything other than Receive / Transmit . < / para >
< / parameter >
< parameter name = " PageNumber " required = " false " >
< para > Current number of pages transferred during this FAX session . May change as the FAX
progresses . This field is not included when operation is ' V .21 Detect ' or if operation is
' gateway ' and state is ' Uninitialized ' . < / para >
< / parameter >
< parameter name = " FileName " required = " false " >
< para > Filename of the image being sent / recieved for this FAX session . This field is not
included if Operation isn ' t ' send ' or ' receive ' . < / para >
< / parameter >
< parameter name = " PagesTransmitted " required = " false " >
< para > Total number of pages sent during this session . This field is not included if
Operation isn ' t ' send ' or ' receive ' . Will always be 0 for ' receive ' . < / para >
< / parameter >
< parameter name = " PagesReceived " required = " false " >
< para > Total number of pages received during this session . This field is not included if
Operation is not ' send ' or ' receive ' . Will be 0 for ' send ' . < / para >
< / parameter >
< parameter name = " TotalBadLines " required = " false " >
< para > Total number of bad lines sent / recieved during this session . This field is not
included if Operation is not ' send ' or ' received ' . < / para >
< / parameter >
< / syntax >
< / managerEventInstance >
< / managerEvent >
< manager name = " FAXStats " language = " en_US " >
< synopsis >
Responds with fax statistics
< / synopsis >
< syntax >
< xi : include xpointer = " xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID']) " / >
< / syntax >
< description >
< para > Provides FAX statistics including the number of active sessions , reserved sessions , completed
sessions , failed sessions , and the number of receive / transmit attempts . This command provides all
of the non - technology specific information provided by the CLI command ' fax show stats ' < / para >
< / description >
< / manager >
< managerEvent language = " en_US " name = " FAXStats " >
< managerEventInstance class = " EVENT_FLAG_REPORTING " >
< synopsis > Raised in response to FAXStats manager command < / synopsis >
< syntax >
< parameter name = " ActionID " required = " false " / >
< parameter name = " CurrentSessions " required = " true " >
< para > Number of active FAX sessions < / para >
< / parameter >
< parameter name = " ReservedSessions " required = " true " >
< para > Number of reserved FAX sessions < / para >
< / parameter >
< parameter name = " TransmitAttempts " required = " true " >
< para > Total FAX sessions for which Asterisk is / was the transmitter < / para >
< / parameter >
< parameter name = " ReceiveAttempts " required = " true " >
< para > Total FAX sessions for which Asterisk is / was the recipient < / para >
< / parameter >
< parameter name = " CompletedFAXes " required = " true " >
< para > Total FAX sessions which have been completed successfully < / para >
< / parameter >
< parameter name = " FailedFAXes " required = " true " >
< para > Total FAX sessions which failed to complete successfully < / para >
< / parameter >
< / syntax >
< / managerEventInstance >
< / managerEvent >
2010-07-17 00:03:37 +00:00
* * */
2010-03-02 23:11:06 +00:00
2010-07-17 00:03:37 +00:00
static const char app_receivefax [ ] = " ReceiveFAX " ;
2010-03-02 23:11:06 +00:00
static const char app_sendfax [ ] = " SendFAX " ;
struct debug_info_history {
unsigned int consec_frames ;
unsigned int consec_ms ;
unsigned char silence ;
} ;
struct ast_fax_debug_info {
struct timeval base_tv ;
struct debug_info_history c2s , s2c ;
struct ast_dsp * dsp ;
} ;
2011-06-30 18:22:28 +00:00
/*! \brief used for gateway framehook */
struct fax_gateway {
/*! \brief FAX Session */
struct ast_fax_session * s ;
2011-12-28 18:59:16 +00:00
struct ast_fax_session * peer_v21_session ;
struct ast_fax_session * chan_v21_session ;
2011-06-30 18:22:28 +00:00
/*! \brief reserved fax session token */
struct ast_fax_tech_token * token ;
/*! \brief the start of our timeout counter */
struct timeval timeout_start ;
/*! \brief framehook used in gateway mode */
int framehook ;
/*! \brief bridged */
int bridged : 1 ;
2011-07-12 15:23:24 +00:00
/*! \brief 1 if a v21 preamble has been detected */
int detected_v21 : 1 ;
2011-06-30 18:22:28 +00:00
/*! \brief a flag to track the state of our negotiation */
enum ast_t38_state t38_state ;
/*! \brief original audio formats */
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
struct ast_format * chan_read_format ;
struct ast_format * chan_write_format ;
struct ast_format * peer_read_format ;
struct ast_format * peer_write_format ;
2011-06-30 18:22:28 +00:00
} ;
2011-10-05 06:50:18 +00:00
/*! \brief used for fax detect framehook */
struct fax_detect {
/*! \brief the start of our timeout counter */
struct timeval timeout_start ;
/*! \brief faxdetect timeout */
int timeout ;
/*! \brief DSP Processor */
struct ast_dsp * dsp ;
/*! \brief original audio formats */
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
struct ast_format * orig_format ;
2011-10-05 06:50:18 +00:00
/*! \brief fax session details */
struct ast_fax_session_details * details ;
/*! \brief mode */
int flags ;
} ;
/*! \brief FAX Detect flags */
# define FAX_DETECT_MODE_CNG (1 << 0)
# define FAX_DETECT_MODE_T38 (1 << 1)
2011-10-21 09:16:12 +00:00
# define FAX_DETECT_MODE_BOTH (FAX_DETECT_MODE_CNG | FAX_DETECT_MODE_T38)
2011-10-05 06:50:18 +00:00
2010-05-21 15:15:58 +00:00
static int fax_logger_level = - 1 ;
2010-03-02 23:11:06 +00:00
/*! \brief maximum buckets for res_fax ao2 containers */
# define FAX_MAXBUCKETS 10
# define RES_FAX_TIMEOUT 10000
2011-06-30 18:22:28 +00:00
# define FAX_GATEWAY_TIMEOUT RES_FAX_TIMEOUT
2010-03-02 23:11:06 +00:00
/*! \brief The faxregistry is used to manage information and statistics for all FAX sessions. */
static struct {
/*! The number of active FAX sessions */
int active_sessions ;
2010-12-03 15:32:22 +00:00
/*! The number of reserved FAX sessions */
int reserved_sessions ;
2010-03-02 23:11:06 +00:00
/*! active sessions are astobj2 objects */
struct ao2_container * container ;
/*! Total number of Tx FAX attempts */
int fax_tx_attempts ;
/*! Total number of Rx FAX attempts */
int fax_rx_attempts ;
/*! Number of successful FAX transmissions */
int fax_complete ;
/*! Number of failed FAX transmissions */
int fax_failures ;
/*! the next unique session name */
int nextsessionname ;
} faxregistry ;
/*! \brief registered FAX technology modules are put into this list */
struct fax_module {
const struct ast_fax_tech * tech ;
AST_RWLIST_ENTRY ( fax_module ) list ;
} ;
static AST_RWLIST_HEAD_STATIC ( faxmodules , fax_module ) ;
2014-01-16 19:13:05 +00:00
# define RES_FAX_MINRATE 4800
2010-03-02 23:11:06 +00:00
# define RES_FAX_MAXRATE 14400
# define RES_FAX_STATUSEVENTS 0
2015-04-29 18:05:10 +00:00
# define RES_FAX_MODEM (AST_FAX_MODEM_V17 | AST_FAX_MODEM_V27TER | AST_FAX_MODEM_V29)
2015-01-09 14:53:09 +00:00
# define RES_FAX_T38TIMEOUT 5000
2010-03-02 23:11:06 +00:00
2012-02-09 17:17:55 +00:00
struct fax_options {
2010-03-02 23:11:06 +00:00
enum ast_fax_modems modems ;
uint32_t statusevents : 1 ;
2010-04-26 14:18:15 +00:00
uint32_t ecm : 1 ;
2011-12-28 18:59:16 +00:00
unsigned int minrate ;
2010-03-02 23:11:06 +00:00
unsigned int maxrate ;
2015-01-09 14:53:09 +00:00
unsigned int t38timeout ;
2012-02-09 17:17:55 +00:00
} ;
static struct fax_options general_options ;
static const struct fax_options default_options = {
. minrate = RES_FAX_MINRATE ,
. maxrate = RES_FAX_MAXRATE ,
. statusevents = RES_FAX_STATUSEVENTS ,
. modems = RES_FAX_MODEM ,
. ecm = AST_FAX_OPTFLAG_TRUE ,
2015-01-09 14:53:09 +00:00
. t38timeout = RES_FAX_T38TIMEOUT ,
2012-02-09 17:17:55 +00:00
} ;
AST_RWLOCK_DEFINE_STATIC ( options_lock ) ;
static void get_general_options ( struct fax_options * options ) ;
static void set_general_options ( const struct fax_options * options ) ;
2010-03-02 23:11:06 +00:00
static const char * config = " res_fax.conf " ;
static int global_fax_debug = 0 ;
enum {
2010-04-26 14:18:15 +00:00
OPT_CALLEDMODE = ( 1 < < 0 ) ,
OPT_CALLERMODE = ( 1 < < 1 ) ,
OPT_DEBUG = ( 1 < < 2 ) ,
OPT_STATUS = ( 1 < < 3 ) ,
OPT_ALLOWAUDIO = ( 1 < < 5 ) ,
OPT_REQUEST_T38 = ( 1 < < 6 ) ,
2011-01-27 15:57:52 +00:00
OPT_FORCE_AUDIO = ( 1 < < 7 ) ,
2010-03-02 23:11:06 +00:00
} ;
AST_APP_OPTIONS ( fax_exec_options , BEGIN_OPTIONS
AST_APP_OPTION ( ' a ' , OPT_CALLEDMODE ) ,
AST_APP_OPTION ( ' c ' , OPT_CALLERMODE ) ,
AST_APP_OPTION ( ' d ' , OPT_DEBUG ) ,
AST_APP_OPTION ( ' f ' , OPT_ALLOWAUDIO ) ,
2011-01-27 15:57:52 +00:00
AST_APP_OPTION ( ' F ' , OPT_FORCE_AUDIO ) ,
2010-03-02 23:11:06 +00:00
AST_APP_OPTION ( ' s ' , OPT_STATUS ) ,
2010-04-26 14:18:15 +00:00
AST_APP_OPTION ( ' z ' , OPT_REQUEST_T38 ) ,
2010-03-02 23:11:06 +00:00
END_OPTIONS ) ;
static void debug_check_frame_for_silence ( struct ast_fax_session * s , unsigned int c2s , struct ast_frame * frame )
2011-12-28 18:59:16 +00:00
{
2010-03-02 23:11:06 +00:00
struct debug_info_history * history = c2s ? & s - > debug_info - > c2s : & s - > debug_info - > s2c ;
int dspsilence ;
unsigned int last_consec_frames , last_consec_ms ;
unsigned char wassil ;
struct timeval diff ;
diff = ast_tvsub ( ast_tvnow ( ) , s - > debug_info - > base_tv ) ;
ast_dsp_reset ( s - > debug_info - > dsp ) ;
ast_dsp_silence ( s - > debug_info - > dsp , frame , & dspsilence ) ;
wassil = history - > silence ;
history - > silence = ( dspsilence ! = 0 ) ? 1 : 0 ;
if ( history - > silence ! = wassil ) {
last_consec_frames = history - > consec_frames ;
last_consec_ms = history - > consec_ms ;
history - > consec_frames = 0 ;
history - > consec_ms = 0 ;
if ( ( last_consec_frames ! = 0 ) ) {
2014-05-28 22:54:12 +00:00
ast_verb ( 0 , " Channel '%s' fax session '%u', [ %.3ld.%.6ld ], %s sent %u frames (%u ms) of %s. \n " ,
2010-03-02 23:11:06 +00:00
s - > channame , s - > id , ( long ) diff . tv_sec , ( long int ) diff . tv_usec ,
( c2s ) ? " channel " : " stack " , last_consec_frames , last_consec_ms ,
( wassil ) ? " silence " : " energy " ) ;
}
}
history - > consec_frames + + ;
history - > consec_ms + = ( frame - > samples / 8 ) ;
}
2011-12-28 18:59:16 +00:00
static void destroy_callback ( void * data )
2010-03-02 23:11:06 +00:00
{
if ( data ) {
ao2_ref ( data , - 1 ) ;
}
}
2014-07-18 16:28:10 +00:00
static void fixup_callback ( void * data , struct ast_channel * old_chan , struct ast_channel * new_chan ) ;
2010-03-02 23:11:06 +00:00
static const struct ast_datastore_info fax_datastore = {
. type = " res_fax " ,
. destroy = destroy_callback ,
2014-07-18 16:28:10 +00:00
. chan_fixup = fixup_callback ,
2010-03-02 23:11:06 +00:00
} ;
2014-07-18 16:28:10 +00:00
static int fax_gateway_attach ( struct ast_channel * chan , struct ast_fax_session_details * details ) ;
static int fax_detect_attach ( struct ast_channel * chan , int timeout , int flags ) ;
static struct ast_fax_session_details * find_or_create_details ( struct ast_channel * chan ) ;
/*! \brief Copies fax detection and gateway framehooks during masquerades
*
* \ note must be called with both old_chan and new_chan locked . Since this
* is only called by do_masquerade , that shouldn ' t be an issue .
*/
static void fixup_callback ( void * data , struct ast_channel * old_chan , struct ast_channel * new_chan )
{
struct ast_fax_session_details * old_details = data ;
struct ast_datastore * datastore = ast_channel_datastore_find ( old_chan , & fax_datastore , NULL ) ;
if ( old_details - > gateway_id > = 0 ) {
struct ast_fax_session_details * new_details = find_or_create_details ( new_chan ) ;
ast_framehook_detach ( old_chan , old_details - > gateway_id ) ;
fax_gateway_attach ( new_chan , new_details ) ;
ao2_cleanup ( new_details ) ;
}
if ( old_details - > faxdetect_id > = 0 ) {
ast_framehook_detach ( old_chan , old_details - > faxdetect_id ) ;
fax_detect_attach ( new_chan , old_details - > faxdetect_timeout , old_details - > faxdetect_flags ) ;
}
if ( datastore ) {
ast_channel_datastore_remove ( old_chan , datastore ) ;
ast_datastore_free ( datastore ) ;
}
}
2010-03-02 23:11:06 +00:00
/*! \brief returns a reference counted pointer to a fax datastore, if it exists */
static struct ast_fax_session_details * find_details ( struct ast_channel * chan )
{
struct ast_fax_session_details * details ;
struct ast_datastore * datastore ;
2011-12-28 18:59:16 +00:00
ast_channel_lock ( chan ) ;
2010-03-02 23:11:06 +00:00
if ( ! ( datastore = ast_channel_datastore_find ( chan , & fax_datastore , NULL ) ) ) {
2011-12-28 18:59:16 +00:00
ast_channel_unlock ( chan ) ;
2010-03-02 23:11:06 +00:00
return NULL ;
}
if ( ! ( details = datastore - > data ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " Huh? channel '%s' has a FAX datastore without data! \n " , ast_channel_name ( chan ) ) ;
2010-03-02 23:11:06 +00:00
ast_channel_unlock ( chan ) ;
return NULL ;
}
2011-12-28 18:59:16 +00:00
ao2_ref ( details , 1 ) ;
ast_channel_unlock ( chan ) ;
2010-03-02 23:11:06 +00:00
return details ;
}
/*! \brief destroy a FAX session details structure */
static void destroy_session_details ( void * details )
{
struct ast_fax_session_details * d = details ;
struct ast_fax_document * doc ;
2011-12-28 18:59:16 +00:00
2010-03-02 23:11:06 +00:00
while ( ( doc = AST_LIST_REMOVE_HEAD ( & d - > documents , next ) ) ) {
ast_free ( doc ) ;
}
2011-12-28 18:59:16 +00:00
ast_string_field_free_memory ( d ) ;
2010-03-02 23:11:06 +00:00
}
/*! \brief create a FAX session details structure */
static struct ast_fax_session_details * session_details_new ( void )
{
struct ast_fax_session_details * d ;
2012-02-09 17:17:55 +00:00
struct fax_options options ;
2010-03-02 23:11:06 +00:00
if ( ! ( d = ao2_alloc ( sizeof ( * d ) , destroy_session_details ) ) ) {
return NULL ;
}
2011-12-28 18:59:16 +00:00
2010-03-02 23:11:06 +00:00
if ( ast_string_field_init ( d , 512 ) ) {
ao2_ref ( d , - 1 ) ;
return NULL ;
}
2012-02-09 17:17:55 +00:00
get_general_options ( & options ) ;
2010-03-02 23:11:06 +00:00
AST_LIST_HEAD_INIT_NOLOCK ( & d - > documents ) ;
/* These options need to be set to the configured default and may be overridden by
* SendFAX , ReceiveFAX , or FAXOPT */
2010-04-26 14:18:15 +00:00
d - > option . request_t38 = AST_FAX_OPTFLAG_FALSE ;
d - > option . send_cng = AST_FAX_OPTFLAG_FALSE ;
d - > option . send_ced = AST_FAX_OPTFLAG_FALSE ;
2012-02-09 17:17:55 +00:00
d - > option . ecm = options . ecm ;
d - > option . statusevents = options . statusevents ;
d - > modems = options . modems ;
d - > minrate = options . minrate ;
d - > maxrate = options . maxrate ;
2015-01-09 14:53:09 +00:00
d - > t38timeout = options . t38timeout ;
2011-06-30 18:22:28 +00:00
d - > gateway_id = - 1 ;
2011-10-05 06:50:18 +00:00
d - > faxdetect_id = - 1 ;
2011-08-30 14:03:02 +00:00
d - > gateway_timeout = 0 ;
2010-03-02 23:11:06 +00:00
return d ;
}
2011-06-30 18:22:28 +00:00
static struct ast_control_t38_parameters our_t38_parameters = {
. version = 0 ,
. max_ifp = 400 ,
. rate = AST_T38_RATE_14400 ,
. rate_management = AST_T38_RATE_MANAGEMENT_TRANSFERRED_TCF ,
} ;
static void t38_parameters_ast_to_fax ( struct ast_fax_t38_parameters * dst , const struct ast_control_t38_parameters * src )
{
dst - > version = src - > version ;
dst - > max_ifp = src - > max_ifp ;
dst - > rate = src - > rate ;
dst - > rate_management = src - > rate_management ;
dst - > fill_bit_removal = src - > fill_bit_removal ;
dst - > transcoding_mmr = src - > transcoding_mmr ;
dst - > transcoding_jbig = src - > transcoding_jbig ;
}
static void t38_parameters_fax_to_ast ( struct ast_control_t38_parameters * dst , const struct ast_fax_t38_parameters * src )
{
dst - > version = src - > version ;
dst - > max_ifp = src - > max_ifp ;
dst - > rate = src - > rate ;
dst - > rate_management = src - > rate_management ;
dst - > fill_bit_removal = src - > fill_bit_removal ;
dst - > transcoding_mmr = src - > transcoding_mmr ;
dst - > transcoding_jbig = src - > transcoding_jbig ;
}
2010-03-02 23:11:06 +00:00
/*! \brief returns a reference counted details structure from the channel's fax datastore. If the datastore
2011-12-28 18:59:16 +00:00
* does not exist it will be created */
2010-03-02 23:11:06 +00:00
static struct ast_fax_session_details * find_or_create_details ( struct ast_channel * chan )
{
struct ast_fax_session_details * details ;
struct ast_datastore * datastore ;
if ( ( details = find_details ( chan ) ) ) {
return details ;
}
/* channel does not have one so we must create one */
if ( ! ( details = session_details_new ( ) ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " channel '%s' can't get a FAX details structure for the datastore! \n " , ast_channel_name ( chan ) ) ;
2010-03-02 23:11:06 +00:00
return NULL ;
}
if ( ! ( datastore = ast_datastore_alloc ( & fax_datastore , NULL ) ) ) {
ao2_ref ( details , - 1 ) ;
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " channel '%s' can't get a datastore! \n " , ast_channel_name ( chan ) ) ;
2010-03-02 23:11:06 +00:00
return NULL ;
}
/* add the datastore to the channel and increment the refcount */
datastore - > data = details ;
2011-06-30 18:22:28 +00:00
/* initialize default T.38 parameters */
t38_parameters_ast_to_fax ( & details - > our_t38_parameters , & our_t38_parameters ) ;
t38_parameters_ast_to_fax ( & details - > their_t38_parameters , & our_t38_parameters ) ;
2010-03-02 23:11:06 +00:00
ao2_ref ( details , 1 ) ;
ast_channel_lock ( chan ) ;
ast_channel_datastore_add ( chan , datastore ) ;
ast_channel_unlock ( chan ) ;
return details ;
}
unsigned int ast_fax_maxrate ( void )
{
2012-02-09 17:17:55 +00:00
struct fax_options options ;
get_general_options ( & options ) ;
return options . maxrate ;
2010-03-02 23:11:06 +00:00
}
unsigned int ast_fax_minrate ( void )
{
2012-02-09 17:17:55 +00:00
struct fax_options options ;
get_general_options ( & options ) ;
return options . minrate ;
2010-03-02 23:11:06 +00:00
}
static int update_modem_bits ( enum ast_fax_modems * bits , const char * value )
2011-12-28 18:59:16 +00:00
{
2010-03-02 23:11:06 +00:00
char * m [ 5 ] , * tok , * v = ( char * ) value ;
int i = 0 , j ;
2012-06-11 15:23:30 +00:00
if ( ! strchr ( v , ' , ' ) ) {
2010-03-02 23:11:06 +00:00
m [ i + + ] = v ;
m [ i ] = NULL ;
} else {
tok = strtok ( v , " , " ) ;
2014-09-26 15:28:39 +00:00
while ( tok & & i < ARRAY_LEN ( m ) - 1 ) {
2010-03-02 23:11:06 +00:00
m [ i + + ] = tok ;
tok = strtok ( NULL , " , " ) ;
}
m [ i ] = NULL ;
}
* bits = 0 ;
for ( j = 0 ; j < i ; j + + ) {
if ( ! strcasecmp ( m [ j ] , " v17 " ) ) {
* bits | = AST_FAX_MODEM_V17 ;
} else if ( ! strcasecmp ( m [ j ] , " v27 " ) ) {
2015-04-29 18:05:10 +00:00
* bits | = AST_FAX_MODEM_V27TER ;
2010-03-02 23:11:06 +00:00
} else if ( ! strcasecmp ( m [ j ] , " v29 " ) ) {
* bits | = AST_FAX_MODEM_V29 ;
} else if ( ! strcasecmp ( m [ j ] , " v34 " ) ) {
* bits | = AST_FAX_MODEM_V34 ;
} else {
ast_log ( LOG_WARNING , " ignoring invalid modem setting: '%s', valid options {v17 | v27 | v29 | v34} \n " , m [ j ] ) ;
}
}
return 0 ;
}
2015-01-15 17:28:51 +00:00
2011-10-03 15:55:28 +00:00
static char * ast_fax_caps_to_str ( enum ast_fax_capabilities caps , char * buf , size_t bufsize )
{
char * out = buf ;
size_t size = bufsize ;
int first = 1 ;
if ( caps & AST_FAX_TECH_SEND ) {
if ( ! first ) {
ast_build_string ( & buf , & size , " , " ) ;
}
ast_build_string ( & buf , & size , " SEND " ) ;
first = 0 ;
}
if ( caps & AST_FAX_TECH_RECEIVE ) {
if ( ! first ) {
ast_build_string ( & buf , & size , " , " ) ;
}
ast_build_string ( & buf , & size , " RECEIVE " ) ;
first = 0 ;
}
if ( caps & AST_FAX_TECH_AUDIO ) {
if ( ! first ) {
ast_build_string ( & buf , & size , " , " ) ;
}
ast_build_string ( & buf , & size , " AUDIO " ) ;
first = 0 ;
}
if ( caps & AST_FAX_TECH_T38 ) {
if ( ! first ) {
ast_build_string ( & buf , & size , " , " ) ;
}
ast_build_string ( & buf , & size , " T38 " ) ;
first = 0 ;
}
if ( caps & AST_FAX_TECH_MULTI_DOC ) {
if ( ! first ) {
ast_build_string ( & buf , & size , " , " ) ;
}
ast_build_string ( & buf , & size , " MULTI_DOC " ) ;
first = 0 ;
}
if ( caps & AST_FAX_TECH_GATEWAY ) {
if ( ! first ) {
ast_build_string ( & buf , & size , " , " ) ;
}
ast_build_string ( & buf , & size , " GATEWAY " ) ;
first = 0 ;
}
2011-12-28 18:59:16 +00:00
if ( caps & AST_FAX_TECH_V21_DETECT ) {
if ( ! first ) {
ast_build_string ( & buf , & size , " , " ) ;
}
ast_build_string ( & buf , & size , " V21 " ) ;
first = 0 ;
}
2011-10-03 15:55:28 +00:00
return out ;
}
2010-03-02 23:11:06 +00:00
static int ast_fax_modem_to_str ( enum ast_fax_modems bits , char * tbuf , size_t bufsize )
{
int count = 0 ;
if ( bits & AST_FAX_MODEM_V17 ) {
strcat ( tbuf , " V17 " ) ;
count + + ;
}
2015-04-29 18:05:10 +00:00
if ( bits & AST_FAX_MODEM_V27TER ) {
2010-03-02 23:11:06 +00:00
if ( count ) {
strcat ( tbuf , " , " ) ;
}
strcat ( tbuf , " V27 " ) ;
count + + ;
}
if ( bits & AST_FAX_MODEM_V29 ) {
if ( count ) {
strcat ( tbuf , " , " ) ;
}
strcat ( tbuf , " V29 " ) ;
count + + ;
}
if ( bits & AST_FAX_MODEM_V34 ) {
if ( count ) {
strcat ( tbuf , " , " ) ;
}
strcat ( tbuf , " V34 " ) ;
count + + ;
}
return 0 ;
}
2010-08-09 14:52:21 +00:00
static int check_modem_rate ( enum ast_fax_modems modems , unsigned int rate )
{
switch ( rate ) {
case 2400 :
case 4800 :
2015-04-29 18:05:10 +00:00
if ( ! ( modems & ( AST_FAX_MODEM_V27TER | AST_FAX_MODEM_V34 ) ) ) {
2010-08-09 14:52:21 +00:00
return 1 ;
}
break ;
case 7200 :
2014-01-16 19:13:05 +00:00
case 9600 :
2015-04-29 18:05:10 +00:00
if ( ! ( modems & ( AST_FAX_MODEM_V17 | AST_FAX_MODEM_V29 | AST_FAX_MODEM_V34 ) ) ) {
2014-01-16 19:13:05 +00:00
return 1 ;
}
break ;
2010-08-09 14:52:21 +00:00
case 12000 :
case 14400 :
if ( ! ( modems & ( AST_FAX_MODEM_V17 | AST_FAX_MODEM_V34 ) ) ) {
return 1 ;
}
break ;
case 28800 :
case 33600 :
if ( ! ( modems & AST_FAX_MODEM_V34 ) ) {
return 1 ;
}
break ;
default :
/* this should never happen */
return 1 ;
}
return 0 ;
}
2010-03-02 23:11:06 +00:00
/*! \brief register a FAX technology module */
int ast_fax_tech_register ( struct ast_fax_tech * tech )
{
struct fax_module * fax ;
if ( ! ( fax = ast_calloc ( 1 , sizeof ( * fax ) ) ) ) {
return - 1 ;
}
fax - > tech = tech ;
AST_RWLIST_WRLOCK ( & faxmodules ) ;
AST_RWLIST_INSERT_TAIL ( & faxmodules , fax , list ) ;
AST_RWLIST_UNLOCK ( & faxmodules ) ;
ast_module_ref ( ast_module_info - > self ) ;
ast_verb ( 3 , " Registered handler for '%s' (%s) \n " , fax - > tech - > type , fax - > tech - > description ) ;
return 0 ;
}
/*! \brief unregister a FAX technology module */
void ast_fax_tech_unregister ( struct ast_fax_tech * tech )
{
struct fax_module * fax ;
ast_verb ( 3 , " Unregistering FAX module type '%s' \n " , tech - > type ) ;
AST_RWLIST_WRLOCK ( & faxmodules ) ;
AST_RWLIST_TRAVERSE_SAFE_BEGIN ( & faxmodules , fax , list ) {
if ( fax - > tech ! = tech ) {
continue ;
}
AST_RWLIST_REMOVE_CURRENT ( list ) ;
ast_module_unref ( ast_module_info - > self ) ;
ast_free ( fax ) ;
ast_verb ( 4 , " Unregistered FAX module type '%s' \n " , tech - > type ) ;
2011-12-28 18:59:16 +00:00
break ;
2010-03-02 23:11:06 +00:00
}
AST_RWLIST_TRAVERSE_SAFE_END ;
AST_RWLIST_UNLOCK ( & faxmodules ) ;
}
/*! \brief convert a ast_fax_state to a string */
const char * ast_fax_state_to_str ( enum ast_fax_state state )
{
switch ( state ) {
case AST_FAX_STATE_UNINITIALIZED :
return " Uninitialized " ;
case AST_FAX_STATE_INITIALIZED :
return " Initialized " ;
case AST_FAX_STATE_OPEN :
return " Open " ;
case AST_FAX_STATE_ACTIVE :
return " Active " ;
case AST_FAX_STATE_COMPLETE :
return " Complete " ;
2011-01-26 19:58:14 +00:00
case AST_FAX_STATE_RESERVED :
return " Reserved " ;
case AST_FAX_STATE_INACTIVE :
return " Inactive " ;
2010-03-02 23:11:06 +00:00
default :
2014-05-09 22:49:26 +00:00
ast_log ( LOG_WARNING , " unhandled FAX state: %u \n " , state ) ;
2010-03-02 23:11:06 +00:00
return " Unknown " ;
}
}
2010-05-21 15:15:58 +00:00
void ast_fax_log ( int level , const char * file , const int line , const char * function , const char * msg )
{
if ( fax_logger_level ! = - 1 ) {
ast_log_dynamic_level ( fax_logger_level , " %s " , msg ) ;
} else {
ast_log ( level , file , line , function , " %s " , msg ) ;
}
}
2010-03-02 23:11:06 +00:00
/*! \brief convert a rate string to a rate */
2010-07-06 19:53:04 +00:00
static unsigned int fax_rate_str_to_int ( const char * ratestr )
2010-03-02 23:11:06 +00:00
{
int rate ;
if ( sscanf ( ratestr , " %d " , & rate ) ! = 1 ) {
ast_log ( LOG_ERROR , " failed to sscanf '%s' to rate \n " , ratestr ) ;
2010-07-06 19:53:04 +00:00
return 0 ;
2010-03-02 23:11:06 +00:00
}
switch ( rate ) {
case 2400 :
case 4800 :
case 7200 :
case 9600 :
case 12000 :
case 14400 :
case 28800 :
case 33600 :
return rate ;
default :
ast_log ( LOG_WARNING , " ignoring invalid rate '%s'. Valid options are {2400 | 4800 | 7200 | 9600 | 12000 | 14400 | 28800 | 33600} \n " , ratestr ) ;
2010-07-06 19:53:04 +00:00
return 0 ;
2010-03-02 23:11:06 +00:00
}
}
2011-06-30 18:22:28 +00:00
/*! \brief Release a session token.
* \ param s a session returned from fax_session_reserve ( )
* \ param token a token generated from fax_session_reserve ( )
*
* This function releases the given token and marks the given session as no
* longer reserved . It is safe to call on a session that is not actually
* reserved and with a NULL token . This is so that sessions returned by
* technologies that do not support reserved sessions don ' t require extra logic
* to handle .
*
* \ note This function DOES NOT release the given fax session , only the given
* token .
*/
2011-01-26 19:58:14 +00:00
static void fax_session_release ( struct ast_fax_session * s , struct ast_fax_tech_token * token )
2010-12-03 15:32:22 +00:00
{
2011-01-26 19:58:14 +00:00
if ( token ) {
s - > tech - > release_token ( token ) ;
2010-12-03 15:32:22 +00:00
}
2011-01-26 19:58:14 +00:00
if ( s - > state = = AST_FAX_STATE_RESERVED ) {
2010-12-03 15:32:22 +00:00
ast_atomic_fetchadd_int ( & faxregistry . reserved_sessions , - 1 ) ;
2011-01-26 19:58:14 +00:00
s - > state = AST_FAX_STATE_INACTIVE ;
2010-12-03 15:32:22 +00:00
}
}
2010-03-02 23:11:06 +00:00
/*! \brief destroy a FAX session structure */
static void destroy_session ( void * session )
{
struct ast_fax_session * s = session ;
if ( s - > tech ) {
2011-01-26 19:58:14 +00:00
fax_session_release ( s , NULL ) ;
2010-03-02 23:11:06 +00:00
if ( s - > tech_pvt ) {
s - > tech - > destroy_session ( s ) ;
}
ast_module_unref ( s - > tech - > module ) ;
}
if ( s - > details ) {
2011-10-05 06:40:40 +00:00
if ( s - > details - > caps & AST_FAX_TECH_GATEWAY ) {
s - > details - > caps & = ~ AST_FAX_TECH_GATEWAY ;
}
2010-03-02 23:11:06 +00:00
ao2_ref ( s - > details , - 1 ) ;
}
2011-12-28 18:59:16 +00:00
2010-03-02 23:11:06 +00:00
if ( s - > debug_info ) {
ast_dsp_free ( s - > debug_info - > dsp ) ;
ast_free ( s - > debug_info ) ;
}
if ( s - > smoother ) {
ast_smoother_free ( s - > smoother ) ;
}
2011-01-26 19:58:14 +00:00
if ( s - > state ! = AST_FAX_STATE_INACTIVE ) {
2010-12-03 15:32:22 +00:00
ast_atomic_fetchadd_int ( & faxregistry . active_sessions , - 1 ) ;
}
2010-03-02 23:11:06 +00:00
ast_free ( s - > channame ) ;
2010-04-26 14:18:15 +00:00
ast_free ( s - > chan_uniqueid ) ;
2010-03-02 23:11:06 +00:00
}
2011-06-30 18:22:28 +00:00
/*! \brief Reserve a fax session.
* \ param details the fax session details
* \ param token a pointer to a place to store a token to be passed to fax_session_new ( ) later
*
* This function reserves a fax session for use later . If the selected fax
* technology does not support reserving sessions a session will still be
* returned but token will not be set .
*
* \ note The reference returned by this function does not get consumed by
* fax_session_new ( ) and must always be dereferenced separately .
*
* \ return NULL or an uninitialized and possibly reserved session
*/
2011-01-26 19:58:14 +00:00
static struct ast_fax_session * fax_session_reserve ( struct ast_fax_session_details * details , struct ast_fax_tech_token * * token )
2010-03-02 23:11:06 +00:00
{
struct ast_fax_session * s ;
struct fax_module * faxmod ;
if ( ! ( s = ao2_alloc ( sizeof ( * s ) , destroy_session ) ) ) {
return NULL ;
}
2011-01-26 19:58:14 +00:00
s - > state = AST_FAX_STATE_INACTIVE ;
2011-06-30 18:22:28 +00:00
s - > details = details ;
ao2_ref ( s - > details , 1 ) ;
2010-12-03 15:32:22 +00:00
/* locate a FAX technology module that can handle said requirements
* Note : the requirements have not yet been finalized as T .38
* negotiation has not yet occured . */
AST_RWLIST_RDLOCK ( & faxmodules ) ;
AST_RWLIST_TRAVERSE ( & faxmodules , faxmod , list ) {
if ( ( faxmod - > tech - > caps & details - > caps ) ! = details - > caps ) {
continue ;
}
ast_debug ( 4 , " Reserving a FAX session from '%s'. \n " , faxmod - > tech - > description ) ;
ast_module_ref ( faxmod - > tech - > module ) ;
s - > tech = faxmod - > tech ;
break ;
}
AST_RWLIST_UNLOCK ( & faxmodules ) ;
if ( ! faxmod ) {
2011-10-03 15:55:28 +00:00
char caps [ 128 ] = " " ;
ast_log ( LOG_ERROR , " Could not locate a FAX technology module with capabilities (%s) \n " , ast_fax_caps_to_str ( details - > caps , caps , sizeof ( caps ) ) ) ;
2010-12-03 15:32:22 +00:00
ao2_ref ( s , - 1 ) ;
return NULL ;
}
if ( ! s - > tech - > reserve_session ) {
ast_debug ( 1 , " Selected FAX technology module (%s) does not support reserving sessions. \n " , s - > tech - > description ) ;
return s ;
}
2011-01-26 19:58:14 +00:00
if ( ! ( * token = s - > tech - > reserve_session ( s ) ) ) {
2010-12-03 15:32:22 +00:00
ao2_ref ( s , - 1 ) ;
return NULL ;
}
2011-01-26 19:58:14 +00:00
s - > state = AST_FAX_STATE_RESERVED ;
2010-12-03 15:32:22 +00:00
ast_atomic_fetchadd_int ( & faxregistry . reserved_sessions , 1 ) ;
return s ;
}
2011-06-30 18:22:28 +00:00
/*! \brief create a FAX session
*
* \ param details details for the session
* \ param chan the channel the session will run on
* \ param reserved a reserved session to base this session on ( can be NULL )
* \ param token the token for a reserved session ( can be NULL )
*
* Create a new fax session based on the given details structure .
*
* \ note The given token is always consumed ( by tech - > new_session ( ) or by
* fax_session_release ( ) in the event of a failure ) . The given reference to a
* reserved session is never consumed and must be dereferenced separately from
* the reference returned by this function .
*
* \ return NULL or a reference to a new fax session
*/
2011-01-26 19:58:14 +00:00
static struct ast_fax_session * fax_session_new ( struct ast_fax_session_details * details , struct ast_channel * chan , struct ast_fax_session * reserved , struct ast_fax_tech_token * token )
2010-12-03 15:32:22 +00:00
{
struct ast_fax_session * s = NULL ;
struct fax_module * faxmod ;
if ( reserved ) {
s = reserved ;
ao2_ref ( reserved , + 1 ) ;
2014-10-14 16:47:02 +00:00
ao2_unlink ( faxregistry . container , reserved ) ;
2010-12-03 15:32:22 +00:00
2011-06-30 18:22:28 +00:00
/* NOTE: we don't consume the reference to the reserved
* session . The session returned from fax_session_new ( ) is a
* new reference and must be derefed in addition to the
* reserved session .
*/
2011-01-26 19:58:14 +00:00
if ( s - > state = = AST_FAX_STATE_RESERVED ) {
2010-12-03 15:32:22 +00:00
ast_atomic_fetchadd_int ( & faxregistry . reserved_sessions , - 1 ) ;
2011-01-26 19:58:14 +00:00
s - > state = AST_FAX_STATE_UNINITIALIZED ;
2010-12-03 15:32:22 +00:00
}
}
if ( ! s & & ! ( s = ao2_alloc ( sizeof ( * s ) , destroy_session ) ) ) {
return NULL ;
}
2010-03-02 23:11:06 +00:00
ast_atomic_fetchadd_int ( & faxregistry . active_sessions , 1 ) ;
2010-12-03 15:32:22 +00:00
s - > state = AST_FAX_STATE_UNINITIALIZED ;
2010-03-02 23:11:06 +00:00
if ( details - > option . debug & & ( details - > caps & AST_FAX_TECH_AUDIO ) ) {
if ( ! ( s - > debug_info = ast_calloc ( 1 , sizeof ( * ( s - > debug_info ) ) ) ) ) {
2011-01-26 19:58:14 +00:00
fax_session_release ( s , token ) ;
2010-03-02 23:11:06 +00:00
ao2_ref ( s , - 1 ) ;
return NULL ;
}
if ( ! ( s - > debug_info - > dsp = ast_dsp_new ( ) ) ) {
ast_free ( s - > debug_info ) ;
s - > debug_info = NULL ;
2011-01-26 19:58:14 +00:00
fax_session_release ( s , token ) ;
2010-03-02 23:11:06 +00:00
ao2_ref ( s , - 1 ) ;
return NULL ;
}
ast_dsp_set_threshold ( s - > debug_info - > dsp , 128 ) ;
2011-12-28 18:59:16 +00:00
}
2010-03-02 23:11:06 +00:00
2012-01-09 22:15:50 +00:00
if ( ! ( s - > channame = ast_strdup ( ast_channel_name ( chan ) ) ) ) {
2011-01-26 19:58:14 +00:00
fax_session_release ( s , token ) ;
2010-03-02 23:11:06 +00:00
ao2_ref ( s , - 1 ) ;
return NULL ;
}
2010-04-26 14:18:15 +00:00
2012-01-24 20:12:09 +00:00
if ( ! ( s - > chan_uniqueid = ast_strdup ( ast_channel_uniqueid ( chan ) ) ) ) {
2011-01-26 19:58:14 +00:00
fax_session_release ( s , token ) ;
2010-04-26 14:18:15 +00:00
ao2_ref ( s , - 1 ) ;
return NULL ;
}
2010-03-02 23:11:06 +00:00
s - > chan = chan ;
2011-06-30 18:22:28 +00:00
if ( ! s - > details ) {
s - > details = details ;
ao2_ref ( s - > details , 1 ) ;
}
2010-03-02 23:11:06 +00:00
details - > id = s - > id = ast_atomic_fetchadd_int ( & faxregistry . nextsessionname , 1 ) ;
2011-01-26 19:58:14 +00:00
if ( ! token ) {
2010-12-03 15:32:22 +00:00
/* locate a FAX technology module that can handle said requirements */
AST_RWLIST_RDLOCK ( & faxmodules ) ;
AST_RWLIST_TRAVERSE ( & faxmodules , faxmod , list ) {
if ( ( faxmod - > tech - > caps & details - > caps ) ! = details - > caps ) {
continue ;
}
ast_debug ( 4 , " Requesting a new FAX session from '%s'. \n " , faxmod - > tech - > description ) ;
ast_module_ref ( faxmod - > tech - > module ) ;
2014-10-14 16:20:59 +00:00
if ( reserved ) {
/* Balance module ref from reserved session */
ast_module_unref ( reserved - > tech - > module ) ;
}
2010-12-03 15:32:22 +00:00
s - > tech = faxmod - > tech ;
break ;
2010-03-02 23:11:06 +00:00
}
2010-12-03 15:32:22 +00:00
AST_RWLIST_UNLOCK ( & faxmodules ) ;
2010-03-02 23:11:06 +00:00
2010-12-03 15:32:22 +00:00
if ( ! faxmod ) {
2011-10-03 15:55:28 +00:00
char caps [ 128 ] = " " ;
ast_log ( LOG_ERROR , " Could not locate a FAX technology module with capabilities (%s) \n " , ast_fax_caps_to_str ( details - > caps , caps , sizeof ( caps ) ) ) ;
2010-12-03 15:32:22 +00:00
ao2_ref ( s , - 1 ) ;
return NULL ;
}
2010-03-02 23:11:06 +00:00
}
2010-12-03 15:32:22 +00:00
2011-01-26 19:58:14 +00:00
if ( ! ( s - > tech_pvt = s - > tech - > new_session ( s , token ) ) ) {
2010-03-02 23:11:06 +00:00
ast_log ( LOG_ERROR , " FAX session failed to initialize. \n " ) ;
ao2_ref ( s , - 1 ) ;
return NULL ;
}
/* link the session to the session container */
if ( ! ( ao2_link ( faxregistry . container , s ) ) ) {
2014-05-09 22:49:26 +00:00
ast_log ( LOG_ERROR , " failed to add FAX session '%u' to container. \n " , s - > id ) ;
2010-03-02 23:11:06 +00:00
ao2_ref ( s , - 1 ) ;
return NULL ;
}
2014-05-09 22:49:26 +00:00
ast_debug ( 4 , " channel '%s' using FAX session '%u' \n " , s - > channame , s - > id ) ;
2010-03-02 23:11:06 +00:00
return s ;
}
2013-05-24 20:44:07 +00:00
/*!
* \ internal
* \ brief Convert the filenames in a fax session into a JSON array
* \ retval NULL on error
* \ retval A \ ref ast_json array on success
*/
static struct ast_json * generate_filenames_json ( struct ast_fax_session_details * details )
2010-03-02 23:11:06 +00:00
{
2013-05-24 20:44:07 +00:00
RAII_VAR ( struct ast_json * , json_array , ast_json_array_create ( ) , ast_json_unref ) ;
struct ast_fax_document * doc ;
if ( ! details | | ! json_array ) {
return NULL ;
}
2010-03-02 23:11:06 +00:00
2013-05-24 20:44:07 +00:00
/* don't process empty lists */
if ( AST_LIST_EMPTY ( & details - > documents ) ) {
return NULL ;
}
AST_LIST_TRAVERSE ( & details - > documents , doc , next ) {
struct ast_json * entry = ast_json_string_create ( doc - > filename ) ;
if ( ! entry ) {
return NULL ;
}
if ( ast_json_array_append ( json_array , entry ) ) {
return NULL ;
}
}
ast_json_ref ( json_array ) ;
return json_array ;
}
2010-06-25 19:42:54 +00:00
2015-01-15 17:28:51 +00:00
/*!
* \ brief Generate a string of filenames using the given prefix and separator .
2010-06-25 19:42:54 +00:00
* \ param details the fax session details
* \ param prefix the prefix to each filename
* \ param separator the separator between filenames
*
* This function generates a string of filenames from the given details
* structure and using the given prefix and separator .
*
* \ retval NULL there was an error generating the string
* \ return the string generated string
*/
static char * generate_filenames_string ( struct ast_fax_session_details * details , char * prefix , char * separator )
{
char * filenames , * c ;
size_t size = 0 ;
int first = 1 ;
struct ast_fax_document * doc ;
/* don't process empty lists */
if ( AST_LIST_EMPTY ( & details - > documents ) ) {
2014-07-18 15:49:46 +00:00
return ast_strdup ( " " ) ;
2010-06-25 19:42:54 +00:00
}
/* Calculate the total length of all of the file names */
AST_LIST_TRAVERSE ( & details - > documents , doc , next ) {
size + = strlen ( separator ) + strlen ( prefix ) + strlen ( doc - > filename ) ;
}
size + = 1 ; /* add space for the terminating null */
if ( ! ( filenames = ast_malloc ( size ) ) ) {
return NULL ;
}
c = filenames ;
ast_build_string ( & c , & size , " %s%s " , prefix , AST_LIST_FIRST ( & details - > documents ) - > filename ) ;
AST_LIST_TRAVERSE ( & details - > documents , doc , next ) {
if ( first ) {
first = 0 ;
continue ;
}
ast_build_string ( & c , & size , " %s%s%s " , separator , prefix , doc - > filename ) ;
}
return filenames ;
}
2010-03-02 23:11:06 +00:00
/*! \brief send a FAX status manager event */
static int report_fax_status ( struct ast_channel * chan , struct ast_fax_session_details * details , const char * status )
{
2013-05-24 20:44:07 +00:00
RAII_VAR ( struct ast_json * , json_object , NULL , ast_json_unref ) ;
RAII_VAR ( struct stasis_message * , message , NULL , ao2_cleanup ) ;
struct ast_json * json_filenames = NULL ;
2010-06-25 19:42:54 +00:00
2013-05-24 20:44:07 +00:00
if ( ! details - > option . statusevents ) {
return 0 ;
}
json_filenames = generate_filenames_json ( details ) ;
if ( ! json_filenames ) {
return - 1 ;
2010-03-02 23:11:06 +00:00
}
2011-06-30 18:22:28 +00:00
2013-05-29 03:22:04 +00:00
json_object = ast_json_pack ( " {s: s, s: s, s: s, s: s, s: o} " ,
2013-05-24 20:44:07 +00:00
" type " , " status " ,
" operation " , ( details - > caps & AST_FAX_TECH_GATEWAY ) ? " gateway " : ( details - > caps & AST_FAX_TECH_RECEIVE ) ? " receive " : " send " ,
" status " , status ,
" local_station_id " , details - > localstationid ,
" filenames " , json_filenames ) ;
if ( ! json_object ) {
return - 1 ;
2011-06-30 18:22:28 +00:00
}
2010-03-02 23:11:06 +00:00
2013-05-24 20:44:07 +00:00
{
SCOPED_CHANNELLOCK ( lock , chan ) ;
2013-05-29 02:26:17 +00:00
message = ast_channel_blob_create_from_cache ( ast_channel_uniqueid ( chan ) , ast_channel_fax_type ( ) , json_object ) ;
2013-05-24 20:44:07 +00:00
if ( ! message ) {
return - 1 ;
}
stasis_publish ( ast_channel_topic ( chan ) , message ) ;
}
2010-03-02 23:11:06 +00:00
return 0 ;
}
2010-07-20 21:01:26 +00:00
/*! \brief Set fax related channel variables. */
static void set_channel_variables ( struct ast_channel * chan , struct ast_fax_session_details * details )
{
char buf [ 10 ] ;
pbx_builtin_setvar_helper ( chan , " FAXSTATUS " , S_OR ( details - > result , NULL ) ) ;
pbx_builtin_setvar_helper ( chan , " FAXERROR " , S_OR ( details - > error , NULL ) ) ;
pbx_builtin_setvar_helper ( chan , " FAXSTATUSSTRING " , S_OR ( details - > resultstr , NULL ) ) ;
pbx_builtin_setvar_helper ( chan , " REMOTESTATIONID " , S_OR ( details - > remotestationid , NULL ) ) ;
2011-03-18 16:03:51 +00:00
pbx_builtin_setvar_helper ( chan , " LOCALSTATIONID " , S_OR ( details - > localstationid , NULL ) ) ;
2010-07-20 21:01:26 +00:00
pbx_builtin_setvar_helper ( chan , " FAXBITRATE " , S_OR ( details - > transfer_rate , NULL ) ) ;
pbx_builtin_setvar_helper ( chan , " FAXRESOLUTION " , S_OR ( details - > resolution , NULL ) ) ;
2014-05-09 22:49:26 +00:00
snprintf ( buf , sizeof ( buf ) , " %u " , details - > pages_transferred ) ;
2010-07-20 21:01:26 +00:00
pbx_builtin_setvar_helper ( chan , " FAXPAGES " , buf ) ;
}
2010-07-29 21:08:42 +00:00
# define GENERIC_FAX_EXEC_SET_VARS(fax, chan, errorstr, reason) \
2010-03-02 23:11:06 +00:00
do { \
2010-12-10 16:53:43 +00:00
if ( ast_strlen_zero ( fax - > details - > result ) ) \
ast_string_field_set ( fax - > details , result , " FAILED " ) ; \
if ( ast_strlen_zero ( fax - > details - > resultstr ) ) \
ast_string_field_set ( fax - > details , resultstr , reason ) ; \
if ( ast_strlen_zero ( fax - > details - > error ) ) \
ast_string_field_set ( fax - > details , error , errorstr ) ; \
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , fax - > details ) ; \
2010-07-29 21:08:42 +00:00
} while ( 0 )
# define GENERIC_FAX_EXEC_ERROR_QUIET(fax, chan, errorstr, reason) \
do { \
GENERIC_FAX_EXEC_SET_VARS ( fax , chan , errorstr , reason ) ; \
2010-03-02 23:11:06 +00:00
} while ( 0 )
2010-07-21 13:03:01 +00:00
# define GENERIC_FAX_EXEC_ERROR(fax, chan, errorstr, reason) \
do { \
2014-05-09 22:49:26 +00:00
ast_log ( LOG_ERROR , " channel '%s' FAX session '%u' failure, reason: '%s' (%s) \n " , ast_channel_name ( chan ) , fax - > id , reason , errorstr ) ; \
2010-07-21 13:03:01 +00:00
GENERIC_FAX_EXEC_ERROR_QUIET ( fax , chan , errorstr , reason ) ; \
} while ( 0 )
2010-04-26 14:18:15 +00:00
static int set_fax_t38_caps ( struct ast_channel * chan , struct ast_fax_session_details * details )
2010-03-02 23:11:06 +00:00
{
2010-04-26 14:18:15 +00:00
switch ( ast_channel_get_t38_state ( chan ) ) {
Improve handling of T.38 re-INVITEs that arrive before a T.38-capable
application is executing on a channel.
This patch addresses an issue found during working with end-users
using res_fax. If an incoming call is answered in the dialplan, or
jumps to the 'fax' extension due to reception of a CNG tone (with
faxdetect enabled), and then the remote endpoint sends a T.38
re-INVITE, it is possible for the channel's T.38 state to be
'T38_STATE_NEGOTIATING' when the application starts up. Unfortunately,
even if the application wants to use T.38, it can't respond to the
peer's negotiation request, because the AST_CONTROL_T38_PARAMETERS
control frame that chan_sip sent originally has been lost, and the
application needs the content of that frame to be able to formulate a
reply.
This patch adds a new 'request' type to AST_CONTROL_T38_PARAMETERS,
AST_T38_REQUEST_PARMS. If the application sends this request, chan_sip
will re-send the original control frame (with
AST_T38_REQUEST_NEGOTIATE as the request type), and the application
can respond as normal. If this occurs within the five second timeout
in chan_sip, the automatic cancellation of the peer reinvite will be
stopped, and the application will 'own' the negotiation process from
that point onwards.
This also improves the code path in chan_sip to allow sip_indicate(),
when called for AST_CONTROL_T38_PARAMETERS, to be able to return a
non-zero response, which should have been in place before since the
control frame *can* fail to be processed properly. It also modifies
ast_indicate() to return whatever result the channel driver returned
for this control frame, rather than converting all non-zero results
into '-1'. Finally, the new request type intentionally returns a
positive value, so that an application that sends
AST_T38_REQUEST_PARMS can know for certain whether the channel driver
accepted it and will be replying with a control frame of its own, or
whether it was ignored (if the sip_indicate()/ast_indicate() path had
properly supported failure responses before, this would not be
necessary).
This patch also modifies res_fax to take advantage of the new request.
In addition, this patch makes sip_t38_abort() actually lock the
private structure before doing its work... bad programmer, no donut.
This patch also enhances chan_sip's 'faxdetect' support to allow
triggering on T.38 re-INVITEs received as well as CNG tone detection.
Review: https://reviewboard.asterisk.org/r/556/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@254450 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-03-25 15:27:31 +00:00
case T38_STATE_UNKNOWN :
details - > caps | = AST_FAX_TECH_T38 ;
break ;
2011-05-16 14:56:53 +00:00
case T38_STATE_REJECTED :
Improve handling of T.38 re-INVITEs that arrive before a T.38-capable
application is executing on a channel.
This patch addresses an issue found during working with end-users
using res_fax. If an incoming call is answered in the dialplan, or
jumps to the 'fax' extension due to reception of a CNG tone (with
faxdetect enabled), and then the remote endpoint sends a T.38
re-INVITE, it is possible for the channel's T.38 state to be
'T38_STATE_NEGOTIATING' when the application starts up. Unfortunately,
even if the application wants to use T.38, it can't respond to the
peer's negotiation request, because the AST_CONTROL_T38_PARAMETERS
control frame that chan_sip sent originally has been lost, and the
application needs the content of that frame to be able to formulate a
reply.
This patch adds a new 'request' type to AST_CONTROL_T38_PARAMETERS,
AST_T38_REQUEST_PARMS. If the application sends this request, chan_sip
will re-send the original control frame (with
AST_T38_REQUEST_NEGOTIATE as the request type), and the application
can respond as normal. If this occurs within the five second timeout
in chan_sip, the automatic cancellation of the peer reinvite will be
stopped, and the application will 'own' the negotiation process from
that point onwards.
This also improves the code path in chan_sip to allow sip_indicate(),
when called for AST_CONTROL_T38_PARAMETERS, to be able to return a
non-zero response, which should have been in place before since the
control frame *can* fail to be processed properly. It also modifies
ast_indicate() to return whatever result the channel driver returned
for this control frame, rather than converting all non-zero results
into '-1'. Finally, the new request type intentionally returns a
positive value, so that an application that sends
AST_T38_REQUEST_PARMS can know for certain whether the channel driver
accepted it and will be replying with a control frame of its own, or
whether it was ignored (if the sip_indicate()/ast_indicate() path had
properly supported failure responses before, this would not be
necessary).
This patch also modifies res_fax to take advantage of the new request.
In addition, this patch makes sip_t38_abort() actually lock the
private structure before doing its work... bad programmer, no donut.
This patch also enhances chan_sip's 'faxdetect' support to allow
triggering on T.38 re-INVITEs received as well as CNG tone detection.
Review: https://reviewboard.asterisk.org/r/556/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@254450 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-03-25 15:27:31 +00:00
case T38_STATE_UNAVAILABLE :
details - > caps | = AST_FAX_TECH_AUDIO ;
break ;
2011-06-30 18:22:28 +00:00
case T38_STATE_NEGOTIATED :
/* already in T.38 mode? This should not happen. */
Improve handling of T.38 re-INVITEs that arrive before a T.38-capable
application is executing on a channel.
This patch addresses an issue found during working with end-users
using res_fax. If an incoming call is answered in the dialplan, or
jumps to the 'fax' extension due to reception of a CNG tone (with
faxdetect enabled), and then the remote endpoint sends a T.38
re-INVITE, it is possible for the channel's T.38 state to be
'T38_STATE_NEGOTIATING' when the application starts up. Unfortunately,
even if the application wants to use T.38, it can't respond to the
peer's negotiation request, because the AST_CONTROL_T38_PARAMETERS
control frame that chan_sip sent originally has been lost, and the
application needs the content of that frame to be able to formulate a
reply.
This patch adds a new 'request' type to AST_CONTROL_T38_PARAMETERS,
AST_T38_REQUEST_PARMS. If the application sends this request, chan_sip
will re-send the original control frame (with
AST_T38_REQUEST_NEGOTIATE as the request type), and the application
can respond as normal. If this occurs within the five second timeout
in chan_sip, the automatic cancellation of the peer reinvite will be
stopped, and the application will 'own' the negotiation process from
that point onwards.
This also improves the code path in chan_sip to allow sip_indicate(),
when called for AST_CONTROL_T38_PARAMETERS, to be able to return a
non-zero response, which should have been in place before since the
control frame *can* fail to be processed properly. It also modifies
ast_indicate() to return whatever result the channel driver returned
for this control frame, rather than converting all non-zero results
into '-1'. Finally, the new request type intentionally returns a
positive value, so that an application that sends
AST_T38_REQUEST_PARMS can know for certain whether the channel driver
accepted it and will be replying with a control frame of its own, or
whether it was ignored (if the sip_indicate()/ast_indicate() path had
properly supported failure responses before, this would not be
necessary).
This patch also modifies res_fax to take advantage of the new request.
In addition, this patch makes sip_t38_abort() actually lock the
private structure before doing its work... bad programmer, no donut.
This patch also enhances chan_sip's 'faxdetect' support to allow
triggering on T.38 re-INVITEs received as well as CNG tone detection.
Review: https://reviewboard.asterisk.org/r/556/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@254450 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-03-25 15:27:31 +00:00
case T38_STATE_NEGOTIATING : {
/* the other end already sent us a T.38 reinvite, so we need to prod the channel
* driver into resending their parameters to us if it supports doing so . . . if
* not , we can ' t proceed , because we can ' t create a proper reply without them .
* if it does work , the channel driver will send an AST_CONTROL_T38_PARAMETERS
* with a request of AST_T38_REQUEST_NEGOTIATE , which will be read by the function
* that gets called after this one completes
*/
struct ast_control_t38_parameters parameters = { . request_response = AST_T38_REQUEST_PARMS , } ;
if ( ast_indicate_data ( chan , AST_CONTROL_T38_PARAMETERS , & parameters , sizeof ( parameters ) ) ! = AST_T38_REQUEST_PARMS ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " channel '%s' is in an unsupported T.38 negotiation state, cannot continue. \n " , ast_channel_name ( chan ) ) ;
Improve handling of T.38 re-INVITEs that arrive before a T.38-capable
application is executing on a channel.
This patch addresses an issue found during working with end-users
using res_fax. If an incoming call is answered in the dialplan, or
jumps to the 'fax' extension due to reception of a CNG tone (with
faxdetect enabled), and then the remote endpoint sends a T.38
re-INVITE, it is possible for the channel's T.38 state to be
'T38_STATE_NEGOTIATING' when the application starts up. Unfortunately,
even if the application wants to use T.38, it can't respond to the
peer's negotiation request, because the AST_CONTROL_T38_PARAMETERS
control frame that chan_sip sent originally has been lost, and the
application needs the content of that frame to be able to formulate a
reply.
This patch adds a new 'request' type to AST_CONTROL_T38_PARAMETERS,
AST_T38_REQUEST_PARMS. If the application sends this request, chan_sip
will re-send the original control frame (with
AST_T38_REQUEST_NEGOTIATE as the request type), and the application
can respond as normal. If this occurs within the five second timeout
in chan_sip, the automatic cancellation of the peer reinvite will be
stopped, and the application will 'own' the negotiation process from
that point onwards.
This also improves the code path in chan_sip to allow sip_indicate(),
when called for AST_CONTROL_T38_PARAMETERS, to be able to return a
non-zero response, which should have been in place before since the
control frame *can* fail to be processed properly. It also modifies
ast_indicate() to return whatever result the channel driver returned
for this control frame, rather than converting all non-zero results
into '-1'. Finally, the new request type intentionally returns a
positive value, so that an application that sends
AST_T38_REQUEST_PARMS can know for certain whether the channel driver
accepted it and will be replying with a control frame of its own, or
whether it was ignored (if the sip_indicate()/ast_indicate() path had
properly supported failure responses before, this would not be
necessary).
This patch also modifies res_fax to take advantage of the new request.
In addition, this patch makes sip_t38_abort() actually lock the
private structure before doing its work... bad programmer, no donut.
This patch also enhances chan_sip's 'faxdetect' support to allow
triggering on T.38 re-INVITEs received as well as CNG tone detection.
Review: https://reviewboard.asterisk.org/r/556/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@254450 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-03-25 15:27:31 +00:00
return - 1 ;
}
details - > caps | = AST_FAX_TECH_T38 ;
break ;
}
default :
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " channel '%s' is in an unsupported T.38 negotiation state, cannot continue. \n " , ast_channel_name ( chan ) ) ;
Improve handling of T.38 re-INVITEs that arrive before a T.38-capable
application is executing on a channel.
This patch addresses an issue found during working with end-users
using res_fax. If an incoming call is answered in the dialplan, or
jumps to the 'fax' extension due to reception of a CNG tone (with
faxdetect enabled), and then the remote endpoint sends a T.38
re-INVITE, it is possible for the channel's T.38 state to be
'T38_STATE_NEGOTIATING' when the application starts up. Unfortunately,
even if the application wants to use T.38, it can't respond to the
peer's negotiation request, because the AST_CONTROL_T38_PARAMETERS
control frame that chan_sip sent originally has been lost, and the
application needs the content of that frame to be able to formulate a
reply.
This patch adds a new 'request' type to AST_CONTROL_T38_PARAMETERS,
AST_T38_REQUEST_PARMS. If the application sends this request, chan_sip
will re-send the original control frame (with
AST_T38_REQUEST_NEGOTIATE as the request type), and the application
can respond as normal. If this occurs within the five second timeout
in chan_sip, the automatic cancellation of the peer reinvite will be
stopped, and the application will 'own' the negotiation process from
that point onwards.
This also improves the code path in chan_sip to allow sip_indicate(),
when called for AST_CONTROL_T38_PARAMETERS, to be able to return a
non-zero response, which should have been in place before since the
control frame *can* fail to be processed properly. It also modifies
ast_indicate() to return whatever result the channel driver returned
for this control frame, rather than converting all non-zero results
into '-1'. Finally, the new request type intentionally returns a
positive value, so that an application that sends
AST_T38_REQUEST_PARMS can know for certain whether the channel driver
accepted it and will be replying with a control frame of its own, or
whether it was ignored (if the sip_indicate()/ast_indicate() path had
properly supported failure responses before, this would not be
necessary).
This patch also modifies res_fax to take advantage of the new request.
In addition, this patch makes sip_t38_abort() actually lock the
private structure before doing its work... bad programmer, no donut.
This patch also enhances chan_sip's 'faxdetect' support to allow
triggering on T.38 re-INVITEs received as well as CNG tone detection.
Review: https://reviewboard.asterisk.org/r/556/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@254450 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2010-03-25 15:27:31 +00:00
return - 1 ;
}
2010-04-26 14:18:15 +00:00
return 0 ;
}
2010-03-02 23:11:06 +00:00
2010-04-26 14:18:15 +00:00
static int disable_t38 ( struct ast_channel * chan )
{
2012-11-07 19:15:26 +00:00
int timeout_ms ;
2010-04-26 14:18:15 +00:00
struct ast_frame * frame = NULL ;
struct ast_control_t38_parameters t38_parameters = { . request_response = AST_T38_REQUEST_TERMINATE , } ;
2012-11-07 19:15:26 +00:00
struct timeval start ;
int ms ;
2010-03-02 23:11:06 +00:00
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " Shutting down T.38 on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
if ( ast_indicate_data ( chan , AST_CONTROL_T38_PARAMETERS , & t38_parameters , sizeof ( t38_parameters ) ) ! = 0 ) {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " error while disabling T.38 on channel '%s' \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
2010-03-02 23:11:06 +00:00
}
2010-04-26 14:18:15 +00:00
/* wait up to five seconds for negotiation to complete */
2012-11-07 19:15:26 +00:00
timeout_ms = 5000 ;
start = ast_tvnow ( ) ;
while ( ( ms = ast_remaining_ms ( start , timeout_ms ) ) ) {
2010-04-26 14:18:15 +00:00
ms = ast_waitfor ( chan , ms ) ;
2012-11-07 19:15:26 +00:00
if ( ms = = 0 ) {
break ;
}
2010-04-26 14:18:15 +00:00
if ( ms < 0 ) {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " error while disabling T.38 on channel '%s' \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
2010-03-02 23:11:06 +00:00
}
2010-04-26 14:18:15 +00:00
if ( ! ( frame = ast_read ( chan ) ) ) {
return - 1 ;
}
if ( ( frame - > frametype = = AST_FRAME_CONTROL ) & &
( frame - > subclass . integer = = AST_CONTROL_T38_PARAMETERS ) & &
( frame - > datalen = = sizeof ( t38_parameters ) ) ) {
struct ast_control_t38_parameters * parameters = frame - > data . ptr ;
switch ( parameters - > request_response ) {
case AST_T38_TERMINATED :
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " Shut down T.38 on %s \n " , ast_channel_name ( chan ) ) ;
2010-03-02 23:11:06 +00:00
break ;
2010-04-26 14:18:15 +00:00
case AST_T38_REFUSED :
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " channel '%s' refused to disable T.38 \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
ast_frfree ( frame ) ;
return - 1 ;
default :
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " channel '%s' failed to disable T.38 \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
ast_frfree ( frame ) ;
2010-03-02 23:11:06 +00:00
return - 1 ;
}
ast_frfree ( frame ) ;
2010-04-26 14:18:15 +00:00
break ;
2010-03-02 23:11:06 +00:00
}
2010-04-26 14:18:15 +00:00
ast_frfree ( frame ) ;
2010-03-02 23:11:06 +00:00
}
2012-11-07 19:15:26 +00:00
if ( ms = = 0 ) { /* all done, nothing happened */
ast_debug ( 1 , " channel '%s' timed-out during T.38 shutdown \n " , ast_channel_name ( chan ) ) ;
}
2010-04-26 14:18:15 +00:00
return 0 ;
}
/*! \brief this is the generic FAX session handling function */
2011-01-26 19:58:14 +00:00
static int generic_fax_exec ( struct ast_channel * chan , struct ast_fax_session_details * details , struct ast_fax_session * reserved , struct ast_fax_tech_token * token )
2010-04-26 14:18:15 +00:00
{
int ms ;
int timeout = RES_FAX_TIMEOUT ;
2012-11-08 22:10:29 +00:00
int chancount ;
2010-04-26 14:18:15 +00:00
unsigned int expected_frametype = - 1 ;
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
struct ast_frame_subclass expected_framesubclass = { . integer = 0 , } ;
2010-04-26 14:18:15 +00:00
unsigned int t38negotiated = ( ast_channel_get_t38_state ( chan ) = = T38_STATE_NEGOTIATED ) ;
struct ast_control_t38_parameters t38_parameters ;
const char * tempvar ;
struct ast_fax_session * fax = NULL ;
struct ast_frame * frame = NULL ;
struct ast_channel * c = chan ;
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
RAII_VAR ( struct ast_format * , orig_write_format , NULL , ao2_cleanup ) ;
RAII_VAR ( struct ast_format * , orig_read_format , NULL , ao2_cleanup ) ;
2012-11-07 19:15:26 +00:00
int remaining_time ;
struct timeval start ;
2010-04-26 14:18:15 +00:00
chancount = 1 ;
2010-03-02 23:11:06 +00:00
/* create the FAX session */
2011-01-26 19:58:14 +00:00
if ( ! ( fax = fax_session_new ( details , chan , reserved , token ) ) ) {
2010-03-02 23:11:06 +00:00
ast_log ( LOG_ERROR , " Can't create a FAX session, FAX attempt failed. \n " ) ;
report_fax_status ( chan , details , " No Available Resource " ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
2010-03-02 23:11:06 +00:00
}
ast_channel_lock ( chan ) ;
2011-12-28 18:59:16 +00:00
/* update session details */
2010-03-02 23:11:06 +00:00
if ( ast_strlen_zero ( details - > headerinfo ) & & ( tempvar = pbx_builtin_getvar_helper ( chan , " LOCALHEADERINFO " ) ) ) {
ast_string_field_set ( details , headerinfo , tempvar ) ;
}
if ( ast_strlen_zero ( details - > localstationid ) ) {
tempvar = pbx_builtin_getvar_helper ( chan , " LOCALSTATIONID " ) ;
ast_string_field_set ( details , localstationid , tempvar ? tempvar : " unknown " ) ;
}
ast_channel_unlock ( chan ) ;
report_fax_status ( chan , details , " Allocating Resources " ) ;
if ( details - > caps & AST_FAX_TECH_AUDIO ) {
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
expected_frametype = AST_FRAME_VOICE ;
expected_framesubclass . format = ast_format_slin ;
orig_write_format = ao2_bump ( ast_channel_writeformat ( chan ) ) ;
if ( ast_set_write_format ( chan , ast_format_slin ) < 0 ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " channel '%s' failed to set write format to signed linear'. \n " , ast_channel_name ( chan ) ) ;
2015-01-15 17:36:37 +00:00
ao2_unlink ( faxregistry . container , fax ) ;
ao2_ref ( fax , - 1 ) ;
2010-03-02 23:11:06 +00:00
return - 1 ;
}
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
orig_read_format = ao2_bump ( ast_channel_readformat ( chan ) ) ;
if ( ast_set_read_format ( chan , ast_format_slin ) < 0 ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " channel '%s' failed to set read format to signed linear. \n " , ast_channel_name ( chan ) ) ;
2015-01-15 17:36:37 +00:00
ao2_unlink ( faxregistry . container , fax ) ;
ao2_ref ( fax , - 1 ) ;
2010-03-02 23:11:06 +00:00
return - 1 ;
}
if ( fax - > smoother ) {
ast_smoother_free ( fax - > smoother ) ;
fax - > smoother = NULL ;
}
if ( ! ( fax - > smoother = ast_smoother_new ( 320 ) ) ) {
2014-05-09 22:49:26 +00:00
ast_log ( LOG_WARNING , " Channel '%s' FAX session '%u' failed to obtain a smoother. \n " , ast_channel_name ( chan ) , fax - > id ) ;
2010-03-02 23:11:06 +00:00
}
} else {
expected_frametype = AST_FRAME_MODEM ;
2011-02-03 16:22:10 +00:00
expected_framesubclass . integer = AST_MODEM_T38 ;
2010-03-02 23:11:06 +00:00
}
if ( fax - > debug_info ) {
fax - > debug_info - > base_tv = ast_tvnow ( ) ;
}
2010-07-07 16:40:19 +00:00
/* reset our result fields just in case the fax tech driver wants to
* set custom error messages */
ast_string_field_set ( details , result , " " ) ;
ast_string_field_set ( details , resultstr , " " ) ;
ast_string_field_set ( details , error , " " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2010-07-07 16:40:19 +00:00
2010-03-02 23:11:06 +00:00
if ( fax - > tech - > start_session ( fax ) < 0 ) {
2010-07-07 16:40:19 +00:00
GENERIC_FAX_EXEC_ERROR ( fax , chan , " INIT_ERROR " , " failed to start FAX session " ) ;
2010-03-02 23:11:06 +00:00
}
report_fax_status ( chan , details , " FAX Transmission In Progress " ) ;
2012-01-09 22:15:50 +00:00
ast_debug ( 5 , " channel %s will wait on FAX fd %d \n " , ast_channel_name ( chan ) , fax - > fd ) ;
2010-03-02 23:11:06 +00:00
/* handle frames for the session */
2012-11-07 19:15:26 +00:00
remaining_time = timeout ;
start = ast_tvnow ( ) ;
while ( remaining_time > 0 ) {
2010-03-02 23:11:06 +00:00
struct ast_channel * ready_chan ;
int ofd , exception ;
ms = 1000 ;
errno = 0 ;
ready_chan = ast_waitfor_nandfds ( & c , chancount , & fax - > fd , 1 , & exception , & ofd , & ms ) ;
if ( ready_chan ) {
if ( ! ( frame = ast_read ( chan ) ) ) {
/* the channel is probably gone, so lets stop polling on it and let the
* FAX session complete before we exit the application . if needed ,
* send the FAX stack silence so the modems can finish their session without
* any problems */
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " Channel '%s' did not return a frame; probably hung up. \n " , ast_channel_name ( chan ) ) ;
2010-07-29 21:08:42 +00:00
GENERIC_FAX_EXEC_SET_VARS ( fax , chan , " HANGUP " , " remote channel hungup " ) ;
2010-03-02 23:11:06 +00:00
c = NULL ;
chancount = 0 ;
2012-11-07 19:15:26 +00:00
remaining_time = ast_remaining_ms ( start , timeout ) ;
2010-03-02 23:11:06 +00:00
fax - > tech - > cancel_session ( fax ) ;
if ( fax - > tech - > generate_silence ) {
fax - > tech - > generate_silence ( fax ) ;
}
continue ;
}
if ( ( frame - > frametype = = AST_FRAME_CONTROL ) & &
( frame - > subclass . integer = = AST_CONTROL_T38_PARAMETERS ) & &
( frame - > datalen = = sizeof ( t38_parameters ) ) ) {
unsigned int was_t38 = t38negotiated ;
struct ast_control_t38_parameters * parameters = frame - > data . ptr ;
2011-12-28 18:59:16 +00:00
2010-03-02 23:11:06 +00:00
switch ( parameters - > request_response ) {
case AST_T38_REQUEST_NEGOTIATE :
/* the other end has requested a switch to T.38, so reply that we are willing, if we can
* do T .38 as well
*/
t38_parameters_fax_to_ast ( & t38_parameters , & details - > our_t38_parameters ) ;
t38_parameters . request_response = ( details - > caps & AST_FAX_TECH_T38 ) ? AST_T38_NEGOTIATED : AST_T38_REFUSED ;
ast_indicate_data ( chan , AST_CONTROL_T38_PARAMETERS , & t38_parameters , sizeof ( t38_parameters ) ) ;
break ;
case AST_T38_NEGOTIATED :
t38_parameters_ast_to_fax ( & details - > their_t38_parameters , parameters ) ;
t38negotiated = 1 ;
break ;
default :
break ;
}
if ( t38negotiated & & ! was_t38 ) {
2015-01-09 14:53:09 +00:00
if ( fax - > tech - > switch_to_t38 ( fax ) ) {
GENERIC_FAX_EXEC_ERROR ( fax , chan , " UNKNOWN " , " T.38 switch failed " ) ;
break ;
}
2010-03-02 23:11:06 +00:00
details - > caps & = ~ AST_FAX_TECH_AUDIO ;
expected_frametype = AST_FRAME_MODEM ;
2011-02-03 16:22:10 +00:00
expected_framesubclass . integer = AST_MODEM_T38 ;
2010-03-02 23:11:06 +00:00
if ( fax - > smoother ) {
ast_smoother_free ( fax - > smoother ) ;
fax - > smoother = NULL ;
}
2011-12-28 18:59:16 +00:00
2010-03-02 23:11:06 +00:00
report_fax_status ( chan , details , " T.38 Negotiated " ) ;
2011-12-28 18:59:16 +00:00
2014-05-09 22:49:26 +00:00
ast_verb ( 3 , " Channel '%s' switched to T.38 FAX session '%u'. \n " , ast_channel_name ( chan ) , fax - > id ) ;
2010-03-02 23:11:06 +00:00
}
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
} else if ( ( frame - > frametype = = expected_frametype ) & & ( expected_framesubclass . integer = = frame - > subclass . integer ) & &
( ( ! frame - > subclass . format & & ! expected_framesubclass . format ) | |
( frame - > subclass . format & & expected_framesubclass . format & &
( ast_format_cmp ( frame - > subclass . format , expected_framesubclass . format ) ! = AST_FORMAT_CMP_NOT_EQUAL ) ) ) ) {
2010-03-02 23:11:06 +00:00
struct ast_frame * f ;
2011-12-28 18:59:16 +00:00
2010-03-02 23:11:06 +00:00
if ( fax - > smoother ) {
/* push the frame into a smoother */
if ( ast_smoother_feed ( fax - > smoother , frame ) < 0 ) {
2010-07-07 16:40:19 +00:00
GENERIC_FAX_EXEC_ERROR ( fax , chan , " UNKNOWN " , " Failed to feed the smoother " ) ;
2010-03-02 23:11:06 +00:00
}
while ( ( f = ast_smoother_read ( fax - > smoother ) ) & & ( f - > data . ptr ) ) {
if ( fax - > debug_info ) {
debug_check_frame_for_silence ( fax , 1 , f ) ;
}
/* write the frame to the FAX stack */
fax - > tech - > write ( fax , f ) ;
fax - > frames_received + + ;
if ( f ! = frame ) {
ast_frfree ( f ) ;
}
}
} else {
/* write the frame to the FAX stack */
fax - > tech - > write ( fax , frame ) ;
fax - > frames_received + + ;
}
2012-11-07 19:15:26 +00:00
start = ast_tvnow ( ) ;
2010-03-02 23:11:06 +00:00
}
ast_frfree ( frame ) ;
} else if ( ofd = = fax - > fd ) {
/* read a frame from the FAX stack and send it out the channel.
* the FAX stack will return a NULL if the FAX session has already completed */
if ( ! ( frame = fax - > tech - > read ( fax ) ) ) {
break ;
}
if ( fax - > debug_info & & ( frame - > frametype = = AST_FRAME_VOICE ) ) {
debug_check_frame_for_silence ( fax , 0 , frame ) ;
}
ast_write ( chan , frame ) ;
fax - > frames_sent + + ;
ast_frfree ( frame ) ;
2012-11-07 19:15:26 +00:00
start = ast_tvnow ( ) ;
2010-03-02 23:11:06 +00:00
} else {
if ( ms & & ( ofd < 0 ) ) {
if ( ( errno = = 0 ) | | ( errno = = EINTR ) ) {
2012-11-07 19:15:26 +00:00
remaining_time = ast_remaining_ms ( start , timeout ) ;
if ( remaining_time < = 0 )
2010-07-20 21:01:26 +00:00
GENERIC_FAX_EXEC_ERROR ( fax , chan , " TIMEOUT " , " fax session timed-out " ) ;
2010-03-02 23:11:06 +00:00
continue ;
} else {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " something bad happened while channel '%s' was polling. \n " , ast_channel_name ( chan ) ) ;
2010-07-20 21:01:26 +00:00
GENERIC_FAX_EXEC_ERROR ( fax , chan , " UNKNOWN " , " error polling data " ) ;
2010-03-02 23:11:06 +00:00
break ;
}
} else {
/* nothing happened */
2012-11-07 19:15:26 +00:00
remaining_time = ast_remaining_ms ( start , timeout ) ;
if ( remaining_time < = 0 ) {
2010-07-07 16:40:19 +00:00
GENERIC_FAX_EXEC_ERROR ( fax , chan , " TIMEOUT " , " fax session timed-out " ) ;
2010-03-02 23:11:06 +00:00
break ;
}
}
}
}
2012-11-07 19:15:26 +00:00
ast_debug ( 3 , " channel '%s' - event loop stopped { timeout: %d, remaining_time: %d } \n " , ast_channel_name ( chan ) , timeout , remaining_time ) ;
2010-03-02 23:11:06 +00:00
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2010-03-02 23:11:06 +00:00
ast_atomic_fetchadd_int ( & faxregistry . fax_complete , 1 ) ;
if ( ! strcasecmp ( details - > result , " FAILED " ) ) {
ast_atomic_fetchadd_int ( & faxregistry . fax_failures , 1 ) ;
}
if ( fax ) {
ao2_unlink ( faxregistry . container , fax ) ;
ao2_ref ( fax , - 1 ) ;
}
/* if the channel is still alive, and we changed its read/write formats,
* restore them now
*/
if ( chancount ) {
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
if ( orig_read_format ) {
ast_set_read_format ( chan , orig_read_format ) ;
2010-03-02 23:11:06 +00:00
}
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
if ( orig_write_format ) {
ast_set_write_format ( chan , orig_write_format ) ;
2010-03-02 23:11:06 +00:00
}
}
2010-04-26 14:18:15 +00:00
/* return the chancount so the calling function can determine if the channel hungup during this FAX session or not */
return chancount ;
}
2010-03-02 23:11:06 +00:00
2010-04-26 14:18:15 +00:00
static int receivefax_t38_init ( struct ast_channel * chan , struct ast_fax_session_details * details )
{
2012-11-07 19:15:26 +00:00
int timeout_ms ;
2010-04-26 14:18:15 +00:00
struct ast_frame * frame = NULL ;
struct ast_control_t38_parameters t38_parameters ;
2012-11-07 19:15:26 +00:00
struct timeval start ;
int ms ;
2010-04-26 14:18:15 +00:00
/* don't send any audio if we've already received a T.38 reinvite */
if ( ast_channel_get_t38_state ( chan ) ! = T38_STATE_NEGOTIATING ) {
/* generate 3 seconds of CED */
if ( ast_playtones_start ( chan , 1024 , " !2100/3000 " , 1 ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error generating CED tone on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
}
2012-11-07 19:15:26 +00:00
timeout_ms = 3000 ;
start = ast_tvnow ( ) ;
while ( ( ms = ast_remaining_ms ( start , timeout_ms ) ) ) {
2010-04-26 14:18:15 +00:00
ms = ast_waitfor ( chan , ms ) ;
2012-11-07 19:15:26 +00:00
2010-04-26 14:18:15 +00:00
if ( ms < 0 ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error while generating CED tone on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
ast_playtones_stop ( chan ) ;
return - 1 ;
}
if ( ms = = 0 ) { /* all done, nothing happened */
break ;
}
if ( ! ( frame = ast_read ( chan ) ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error reading frame while generating CED tone on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
ast_playtones_stop ( chan ) ;
return - 1 ;
}
if ( ( frame - > frametype = = AST_FRAME_CONTROL ) & &
( frame - > subclass . integer = = AST_CONTROL_T38_PARAMETERS ) & &
( frame - > datalen = = sizeof ( t38_parameters ) ) ) {
struct ast_control_t38_parameters * parameters = frame - > data . ptr ;
switch ( parameters - > request_response ) {
case AST_T38_REQUEST_NEGOTIATE :
/* the other end has requested a switch to T.38, so reply that we are willing, if we can
* do T .38 as well
*/
t38_parameters_fax_to_ast ( & t38_parameters , & details - > our_t38_parameters ) ;
t38_parameters . request_response = ( details - > caps & AST_FAX_TECH_T38 ) ? AST_T38_NEGOTIATED : AST_T38_REFUSED ;
ast_indicate_data ( chan , AST_CONTROL_T38_PARAMETERS , & t38_parameters , sizeof ( t38_parameters ) ) ;
ast_playtones_stop ( chan ) ;
break ;
case AST_T38_NEGOTIATED :
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " Negotiated T.38 for receive on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
t38_parameters_ast_to_fax ( & details - > their_t38_parameters , parameters ) ;
details - > caps & = ~ AST_FAX_TECH_AUDIO ;
report_fax_status ( chan , details , " T.38 Negotiated " ) ;
break ;
default :
2010-03-02 23:11:06 +00:00
break ;
}
}
2010-04-26 14:18:15 +00:00
ast_frfree ( frame ) ;
2010-03-02 23:11:06 +00:00
}
2010-04-26 14:18:15 +00:00
ast_playtones_stop ( chan ) ;
2010-03-02 23:11:06 +00:00
}
2010-04-26 14:18:15 +00:00
/* if T.38 was negotiated, we are done initializing */
if ( ast_channel_get_t38_state ( chan ) = = T38_STATE_NEGOTIATED ) {
return 0 ;
}
/* request T.38 */
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " Negotiating T.38 for receive on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
2015-01-09 14:53:09 +00:00
/* wait for negotiation to complete */
timeout_ms = details - > t38timeout ;
2010-04-26 14:18:15 +00:00
/* set parameters based on the session's parameters */
t38_parameters_fax_to_ast ( & t38_parameters , & details - > our_t38_parameters ) ;
t38_parameters . request_response = AST_T38_REQUEST_NEGOTIATE ;
if ( ( ast_indicate_data ( chan , AST_CONTROL_T38_PARAMETERS , & t38_parameters , sizeof ( t38_parameters ) ) ! = 0 ) ) {
return - 1 ;
}
2012-11-07 19:15:26 +00:00
start = ast_tvnow ( ) ;
while ( ( ms = ast_remaining_ms ( start , timeout_ms ) ) ) {
int break_loop = 0 ;
2010-04-26 14:18:15 +00:00
ms = ast_waitfor ( chan , ms ) ;
if ( ms < 0 ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " error on '%s' while waiting for T.38 negotiation. \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
}
if ( ms = = 0 ) { /* all done, nothing happened */
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " channel '%s' timed-out during the T.38 negotiation. \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
details - > caps & = ~ AST_FAX_TECH_T38 ;
break ;
}
if ( ! ( frame = ast_read ( chan ) ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " error on '%s' while waiting for T.38 negotiation. \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
}
if ( ( frame - > frametype = = AST_FRAME_CONTROL ) & &
( frame - > subclass . integer = = AST_CONTROL_T38_PARAMETERS ) & &
( frame - > datalen = = sizeof ( t38_parameters ) ) ) {
struct ast_control_t38_parameters * parameters = frame - > data . ptr ;
switch ( parameters - > request_response ) {
case AST_T38_REQUEST_NEGOTIATE :
t38_parameters_fax_to_ast ( & t38_parameters , & details - > our_t38_parameters ) ;
t38_parameters . request_response = AST_T38_NEGOTIATED ;
ast_indicate_data ( chan , AST_CONTROL_T38_PARAMETERS , & t38_parameters , sizeof ( t38_parameters ) ) ;
break ;
case AST_T38_NEGOTIATED :
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " Negotiated T.38 for receive on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
t38_parameters_ast_to_fax ( & details - > their_t38_parameters , parameters ) ;
details - > caps & = ~ AST_FAX_TECH_AUDIO ;
report_fax_status ( chan , details , " T.38 Negotiated " ) ;
2012-11-07 19:15:26 +00:00
break_loop = 1 ;
2010-04-26 14:18:15 +00:00
break ;
case AST_T38_REFUSED :
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " channel '%s' refused to negotiate T.38 \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
details - > caps & = ~ AST_FAX_TECH_T38 ;
2012-11-07 19:15:26 +00:00
break_loop = 1 ;
2010-04-26 14:18:15 +00:00
break ;
default :
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " channel '%s' failed to negotiate T.38 \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
details - > caps & = ~ AST_FAX_TECH_T38 ;
2012-11-07 19:15:26 +00:00
break_loop = 1 ;
2010-04-26 14:18:15 +00:00
break ;
}
}
ast_frfree ( frame ) ;
2012-11-07 19:15:26 +00:00
if ( break_loop ) {
break ;
}
2010-04-26 14:18:15 +00:00
}
/* if T.38 was negotiated, we are done initializing */
if ( ast_channel_get_t38_state ( chan ) = = T38_STATE_NEGOTIATED ) {
return 0 ;
}
/* if we made it here, then T.38 failed, check the 'f' flag */
if ( details - > option . allow_audio ! = AST_FAX_OPTFLAG_TRUE ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting. \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
}
/* ok, audio fallback is allowed */
details - > caps | = AST_FAX_TECH_AUDIO ;
return 0 ;
2010-03-02 23:11:06 +00:00
}
2013-05-24 20:44:07 +00:00
/*! \brief Report on the final state of a receive fax operation
* \ note This will lock the \ ref ast_channel
*/
static int report_receive_fax_status ( struct ast_channel * chan , const char * filename )
{
RAII_VAR ( struct ast_json * , json_object , NULL , ast_json_unref ) ;
RAII_VAR ( struct stasis_message * , message , NULL , ao2_cleanup ) ;
RAII_VAR ( struct ast_json * , json_array , ast_json_array_create ( ) , ast_json_unref ) ;
struct ast_json * json_filename = ast_json_string_create ( filename ) ;
if ( ! json_array | | ! json_filename ) {
2014-02-21 18:04:54 +00:00
ast_json_unref ( json_filename ) ;
2013-05-24 20:44:07 +00:00
return - 1 ;
}
ast_json_array_append ( json_array , json_filename ) ;
{
2013-06-22 13:58:07 +00:00
const char * remote_station_id ;
const char * local_station_id ;
const char * fax_pages ;
const char * fax_resolution ;
const char * fax_bitrate ;
2013-05-24 20:44:07 +00:00
SCOPED_CHANNELLOCK ( lock , chan ) ;
2013-06-22 13:58:07 +00:00
remote_station_id = S_OR ( pbx_builtin_getvar_helper ( chan , " REMOTESTATIONID " ) , " " ) ;
2013-06-22 22:42:34 +00:00
if ( ! ast_strlen_zero ( remote_station_id ) ) {
remote_station_id = ast_strdupa ( remote_station_id ) ;
}
2013-06-22 13:58:07 +00:00
local_station_id = S_OR ( pbx_builtin_getvar_helper ( chan , " LOCALSTATIONID " ) , " " ) ;
2013-06-22 22:42:34 +00:00
if ( ! ast_strlen_zero ( local_station_id ) ) {
local_station_id = ast_strdupa ( local_station_id ) ;
}
2013-06-22 13:58:07 +00:00
fax_pages = S_OR ( pbx_builtin_getvar_helper ( chan , " FAXPAGES " ) , " " ) ;
2013-06-22 22:42:34 +00:00
if ( ! ast_strlen_zero ( fax_pages ) ) {
fax_pages = ast_strdupa ( fax_pages ) ;
}
2013-06-22 13:58:07 +00:00
fax_resolution = S_OR ( pbx_builtin_getvar_helper ( chan , " FAXRESOLUTION " ) , " " ) ;
2013-06-22 22:42:34 +00:00
if ( ! ast_strlen_zero ( fax_resolution ) ) {
fax_resolution = ast_strdupa ( fax_resolution ) ;
}
2013-06-22 13:58:07 +00:00
fax_bitrate = S_OR ( pbx_builtin_getvar_helper ( chan , " FAXBITRATE " ) , " " ) ;
2013-06-22 22:42:34 +00:00
if ( ! ast_strlen_zero ( fax_bitrate ) ) {
fax_bitrate = ast_strdupa ( fax_bitrate ) ;
}
2013-06-22 13:58:07 +00:00
json_object = ast_json_pack ( " {s: s, s: s, s: s, s: s, s: s, s: s, s: O} " ,
" type " , " receive " ,
2013-06-22 22:42:34 +00:00
" remote_station_id " , S_OR ( remote_station_id , " " ) ,
" local_station_id " , S_OR ( local_station_id , " " ) ,
" fax_pages " , S_OR ( fax_pages , " " ) ,
" fax_resolution " , S_OR ( fax_resolution , " " ) ,
" fax_bitrate " , S_OR ( fax_bitrate , " " ) ,
2013-05-24 20:44:07 +00:00
" filenames " , json_array ) ;
if ( ! json_object ) {
return - 1 ;
}
2013-05-29 02:26:17 +00:00
message = ast_channel_blob_create_from_cache ( ast_channel_uniqueid ( chan ) , ast_channel_fax_type ( ) , json_object ) ;
2013-05-24 20:44:07 +00:00
if ( ! message ) {
return - 1 ;
}
stasis_publish ( ast_channel_topic ( chan ) , message ) ;
}
return 0 ;
}
2010-03-02 23:11:06 +00:00
/*! \brief initiate a receive FAX session */
static int receivefax_exec ( struct ast_channel * chan , const char * data )
{
2010-08-09 14:52:21 +00:00
char * parse , modems [ 128 ] = " " ;
2010-03-02 23:11:06 +00:00
int channel_alive ;
2013-05-24 20:44:07 +00:00
RAII_VAR ( struct ast_fax_session * , s , NULL , ao2_cleanup ) ;
2013-05-26 16:49:28 +00:00
RAII_VAR ( struct ast_fax_session_details * , details , NULL , ao2_cleanup ) ;
2011-01-26 19:58:14 +00:00
struct ast_fax_tech_token * token = NULL ;
2010-03-02 23:11:06 +00:00
struct ast_fax_document * doc ;
AST_DECLARE_APP_ARGS ( args ,
AST_APP_ARG ( filename ) ;
AST_APP_ARG ( options ) ;
) ;
struct ast_flags opts = { 0 , } ;
2011-05-16 14:56:53 +00:00
enum ast_t38_state t38state ;
2010-03-02 23:11:06 +00:00
2010-07-20 21:01:26 +00:00
/* initialize output channel variables */
pbx_builtin_setvar_helper ( chan , " FAXSTATUS " , " FAILED " ) ;
pbx_builtin_setvar_helper ( chan , " REMOTESTATIONID " , NULL ) ;
pbx_builtin_setvar_helper ( chan , " FAXPAGES " , " 0 " ) ;
pbx_builtin_setvar_helper ( chan , " FAXBITRATE " , NULL ) ;
pbx_builtin_setvar_helper ( chan , " FAXRESOLUTION " , NULL ) ;
2010-07-07 16:40:19 +00:00
/* Get a FAX session details structure from the channel's FAX datastore and create one if
* it does not already exist . */
if ( ! ( details = find_or_create_details ( chan ) ) ) {
2010-07-20 21:01:26 +00:00
pbx_builtin_setvar_helper ( chan , " FAXERROR " , " MEMORY_ERROR " ) ;
pbx_builtin_setvar_helper ( chan , " FAXSTATUSSTRING " , " error allocating memory " ) ;
2010-07-07 16:40:19 +00:00
ast_log ( LOG_ERROR , " System cannot provide memory for session requirements. \n " ) ;
return - 1 ;
}
2010-08-04 15:22:02 +00:00
ast_string_field_set ( details , result , " FAILED " ) ;
ast_string_field_set ( details , resultstr , " error starting fax session " ) ;
ast_string_field_set ( details , error , " INIT_ERROR " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2010-07-07 16:40:19 +00:00
2011-10-05 06:40:40 +00:00
if ( details - > gateway_id > 0 ) {
2011-06-30 18:22:28 +00:00
ast_string_field_set ( details , resultstr , " can't receive a fax on a channel with a T.38 gateway " ) ;
set_channel_variables ( chan , details ) ;
ast_log ( LOG_ERROR , " executing ReceiveFAX on a channel with a T.38 Gateway is not supported \n " ) ;
return - 1 ;
}
2010-08-09 14:52:21 +00:00
if ( details - > maxrate < details - > minrate ) {
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " maxrate is less than minrate " ) ;
set_channel_variables ( chan , details ) ;
2014-05-09 22:49:26 +00:00
ast_log ( LOG_ERROR , " maxrate %u is less than minrate %u \n " , details - > maxrate , details - > minrate ) ;
2010-08-09 14:52:21 +00:00
return - 1 ;
}
if ( check_modem_rate ( details - > modems , details - > minrate ) ) {
ast_fax_modem_to_str ( details - > modems , modems , sizeof ( modems ) ) ;
2014-05-09 22:49:26 +00:00
ast_log ( LOG_ERROR , " 'modems' setting '%s' is incompatible with 'minrate' setting %u \n " , modems , details - > minrate ) ;
2010-08-09 14:52:21 +00:00
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " incompatible 'modems' and 'minrate' settings " ) ;
set_channel_variables ( chan , details ) ;
return - 1 ;
}
if ( check_modem_rate ( details - > modems , details - > maxrate ) ) {
ast_fax_modem_to_str ( details - > modems , modems , sizeof ( modems ) ) ;
2014-05-09 22:49:26 +00:00
ast_log ( LOG_ERROR , " 'modems' setting '%s' is incompatible with 'maxrate' setting %u \n " , modems , details - > maxrate ) ;
2010-08-09 14:52:21 +00:00
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " incompatible 'modems' and 'maxrate' settings " ) ;
set_channel_variables ( chan , details ) ;
return - 1 ;
}
2010-03-02 23:11:06 +00:00
if ( ast_strlen_zero ( data ) ) {
2010-07-07 16:40:19 +00:00
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " invalid arguments " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2010-03-02 23:11:06 +00:00
ast_log ( LOG_WARNING , " %s requires an argument (filename[,options]) \n " , app_receivefax ) ;
return - 1 ;
}
parse = ast_strdupa ( data ) ;
AST_STANDARD_APP_ARGS ( args , parse ) ;
if ( ! ast_strlen_zero ( args . options ) & &
ast_app_parse_options ( fax_exec_options , & opts , NULL , args . options ) ) {
2010-07-20 21:01:26 +00:00
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " invalid arguments " ) ;
set_channel_variables ( chan , details ) ;
2010-03-02 23:11:06 +00:00
return - 1 ;
}
if ( ast_strlen_zero ( args . filename ) ) {
2010-07-07 16:40:19 +00:00
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " invalid arguments " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2010-03-02 23:11:06 +00:00
ast_log ( LOG_WARNING , " %s requires an argument (filename[,options]) \n " , app_receivefax ) ;
return - 1 ;
}
/* check for unsupported FAX application options */
if ( ast_test_flag ( & opts , OPT_CALLERMODE ) | | ast_test_flag ( & opts , OPT_CALLEDMODE ) ) {
2010-07-07 16:40:19 +00:00
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " invalid arguments " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2010-03-02 23:11:06 +00:00
ast_log ( LOG_WARNING , " %s does not support polling \n " , app_receivefax ) ;
return - 1 ;
}
2011-12-28 18:59:16 +00:00
2010-03-02 23:11:06 +00:00
ast_atomic_fetchadd_int ( & faxregistry . fax_rx_attempts , 1 ) ;
pbx_builtin_setvar_helper ( chan , " FAXERROR " , " Channel Problems " ) ;
pbx_builtin_setvar_helper ( chan , " FAXSTATUSSTRING " , " Error before FAX transmission started. " ) ;
if ( ! ( doc = ast_calloc ( 1 , sizeof ( * doc ) + strlen ( args . filename ) + 1 ) ) ) {
2010-07-07 16:40:19 +00:00
ast_string_field_set ( details , error , " MEMORY_ERROR " ) ;
ast_string_field_set ( details , resultstr , " error allocating memory " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2010-03-02 23:11:06 +00:00
ast_log ( LOG_ERROR , " System cannot provide memory for session requirements. \n " ) ;
return - 1 ;
}
strcpy ( doc - > filename , args . filename ) ;
AST_LIST_INSERT_TAIL ( & details - > documents , doc , next ) ;
2012-01-09 22:15:50 +00:00
ast_verb ( 3 , " Channel '%s' receiving FAX '%s' \n " , ast_channel_name ( chan ) , args . filename ) ;
2010-03-02 23:11:06 +00:00
details - > caps = AST_FAX_TECH_RECEIVE ;
2012-12-10 16:56:37 +00:00
details - > option . send_ced = AST_FAX_OPTFLAG_TRUE ;
2010-03-02 23:11:06 +00:00
/* check for debug */
if ( ast_test_flag ( & opts , OPT_DEBUG ) | | global_fax_debug ) {
details - > option . debug = AST_FAX_OPTFLAG_TRUE ;
}
/* check for request for status events */
if ( ast_test_flag ( & opts , OPT_STATUS ) ) {
details - > option . statusevents = AST_FAX_OPTFLAG_TRUE ;
}
2011-05-16 14:56:53 +00:00
t38state = ast_channel_get_t38_state ( chan ) ;
if ( ( t38state = = T38_STATE_UNAVAILABLE ) | | ( t38state = = T38_STATE_REJECTED ) | |
2011-01-26 22:39:07 +00:00
ast_test_flag ( & opts , OPT_ALLOWAUDIO ) | |
2011-01-27 15:57:52 +00:00
ast_test_flag ( & opts , OPT_FORCE_AUDIO ) ) {
2010-03-02 23:11:06 +00:00
details - > option . allow_audio = AST_FAX_OPTFLAG_TRUE ;
}
2011-01-26 19:58:14 +00:00
if ( ! ( s = fax_session_reserve ( details , & token ) ) ) {
2010-12-03 15:32:22 +00:00
ast_string_field_set ( details , resultstr , " error reserving fax session " ) ;
set_channel_variables ( chan , details ) ;
ast_log ( LOG_ERROR , " Unable to reserve FAX session. \n " ) ;
return - 1 ;
}
/* make sure the channel is up */
2012-02-20 23:43:27 +00:00
if ( ast_channel_state ( chan ) ! = AST_STATE_UP ) {
2010-12-03 15:32:22 +00:00
if ( ast_answer ( chan ) ) {
ast_string_field_set ( details , resultstr , " error answering channel " ) ;
set_channel_variables ( chan , details ) ;
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " Channel '%s' failed answer attempt. \n " , ast_channel_name ( chan ) ) ;
2011-01-26 19:58:14 +00:00
fax_session_release ( s , token ) ;
2010-12-03 15:32:22 +00:00
return - 1 ;
}
}
2011-01-27 15:57:52 +00:00
if ( ! ast_test_flag ( & opts , OPT_FORCE_AUDIO ) ) {
2011-01-26 22:39:07 +00:00
if ( set_fax_t38_caps ( chan , details ) ) {
ast_string_field_set ( details , error , " T38_NEG_ERROR " ) ;
ast_string_field_set ( details , resultstr , " error negotiating T.38 " ) ;
set_channel_variables ( chan , details ) ;
fax_session_release ( s , token ) ;
return - 1 ;
}
2011-01-27 20:07:05 +00:00
} else {
details - > caps | = AST_FAX_TECH_AUDIO ;
2010-04-26 14:18:15 +00:00
}
2011-01-27 15:57:52 +00:00
if ( ! ast_test_flag ( & opts , OPT_FORCE_AUDIO ) & & ( details - > caps & AST_FAX_TECH_T38 ) ) {
2010-04-26 14:18:15 +00:00
if ( receivefax_t38_init ( chan , details ) ) {
2010-07-07 16:40:19 +00:00
ast_string_field_set ( details , error , " T38_NEG_ERROR " ) ;
ast_string_field_set ( details , resultstr , " error negotiating T.38 " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2011-01-26 19:58:14 +00:00
fax_session_release ( s , token ) ;
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error initializing channel '%s' in T.38 mode \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
}
}
2011-01-26 19:58:14 +00:00
if ( ( channel_alive = generic_fax_exec ( chan , details , s , token ) ) < 0 ) {
2010-03-02 23:11:06 +00:00
ast_atomic_fetchadd_int ( & faxregistry . fax_failures , 1 ) ;
}
2010-04-26 14:18:15 +00:00
if ( ast_channel_get_t38_state ( chan ) = = T38_STATE_NEGOTIATED ) {
if ( disable_t38 ( chan ) ) {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " error disabling T.38 mode on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
}
}
2013-05-24 20:44:07 +00:00
if ( report_receive_fax_status ( chan , args . filename ) ) {
ast_log ( AST_LOG_ERROR , " Error publishing ReceiveFax status message \n " ) ;
}
2010-03-02 23:11:06 +00:00
/* If the channel hungup return -1; otherwise, return 0 to continue in the dialplan */
return ( ! channel_alive ) ? - 1 : 0 ;
}
2010-04-26 14:18:15 +00:00
static int sendfax_t38_init ( struct ast_channel * chan , struct ast_fax_session_details * details )
{
2012-11-07 19:15:26 +00:00
int timeout_ms ;
2010-04-26 14:18:15 +00:00
struct ast_frame * frame = NULL ;
struct ast_control_t38_parameters t38_parameters ;
2012-11-07 19:15:26 +00:00
struct timeval start ;
int ms ;
2010-04-26 14:18:15 +00:00
/* send CNG tone while listening for the receiver to initiate a switch
* to T .38 mode ; if they do , stop sending the CNG tone and proceed with
* the switch .
*
* 10500 is enough time for 3 CNG tones
*/
2012-11-07 19:15:26 +00:00
timeout_ms = 10500 ;
2010-04-26 14:18:15 +00:00
/* don't send any audio if we've already received a T.38 reinvite */
if ( ast_channel_get_t38_state ( chan ) ! = T38_STATE_NEGOTIATING ) {
if ( ast_playtones_start ( chan , 1024 , " !1100/500,!0/3000,!1100/500,!0/3000,!1100/500,!0/3000 " , 1 ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error generating CNG tone on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
}
}
2012-11-07 19:15:26 +00:00
start = ast_tvnow ( ) ;
while ( ( ms = ast_remaining_ms ( start , timeout_ms ) ) ) {
int break_loop = 0 ;
2010-04-26 14:18:15 +00:00
ms = ast_waitfor ( chan , ms ) ;
2012-11-07 19:15:26 +00:00
2010-04-26 14:18:15 +00:00
if ( ms < 0 ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error while generating CNG tone on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
ast_playtones_stop ( chan ) ;
return - 1 ;
}
if ( ms = = 0 ) { /* all done, nothing happened */
break ;
}
if ( ! ( frame = ast_read ( chan ) ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error reading frame while generating CNG tone on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
ast_playtones_stop ( chan ) ;
return - 1 ;
}
if ( ( frame - > frametype = = AST_FRAME_CONTROL ) & &
( frame - > subclass . integer = = AST_CONTROL_T38_PARAMETERS ) & &
( frame - > datalen = = sizeof ( t38_parameters ) ) ) {
struct ast_control_t38_parameters * parameters = frame - > data . ptr ;
switch ( parameters - > request_response ) {
case AST_T38_REQUEST_NEGOTIATE :
/* the other end has requested a switch to T.38, so reply that we are willing, if we can
* do T .38 as well
*/
t38_parameters_fax_to_ast ( & t38_parameters , & details - > our_t38_parameters ) ;
t38_parameters . request_response = ( details - > caps & AST_FAX_TECH_T38 ) ? AST_T38_NEGOTIATED : AST_T38_REFUSED ;
ast_indicate_data ( chan , AST_CONTROL_T38_PARAMETERS , & t38_parameters , sizeof ( t38_parameters ) ) ;
ast_playtones_stop ( chan ) ;
break ;
case AST_T38_NEGOTIATED :
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " Negotiated T.38 for send on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
t38_parameters_ast_to_fax ( & details - > their_t38_parameters , parameters ) ;
details - > caps & = ~ AST_FAX_TECH_AUDIO ;
report_fax_status ( chan , details , " T.38 Negotiated " ) ;
2012-11-07 19:15:26 +00:00
break_loop = 1 ;
2010-04-26 14:18:15 +00:00
break ;
default :
break ;
}
}
ast_frfree ( frame ) ;
2012-11-07 19:15:26 +00:00
if ( break_loop ) {
break ;
}
2010-04-26 14:18:15 +00:00
}
ast_playtones_stop ( chan ) ;
if ( ast_channel_get_t38_state ( chan ) = = T38_STATE_NEGOTIATED ) {
return 0 ;
}
/* T.38 negotiation did not happen, initiate a switch if requested */
if ( details - > option . request_t38 = = AST_FAX_OPTFLAG_TRUE ) {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " Negotiating T.38 for send on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
/* wait up to five seconds for negotiation to complete */
2012-11-07 19:15:26 +00:00
timeout_ms = 5000 ;
2010-04-26 14:18:15 +00:00
/* set parameters based on the session's parameters */
t38_parameters_fax_to_ast ( & t38_parameters , & details - > our_t38_parameters ) ;
t38_parameters . request_response = AST_T38_REQUEST_NEGOTIATE ;
if ( ( ast_indicate_data ( chan , AST_CONTROL_T38_PARAMETERS , & t38_parameters , sizeof ( t38_parameters ) ) ! = 0 ) ) {
return - 1 ;
}
2012-11-07 19:15:26 +00:00
start = ast_tvnow ( ) ;
while ( ( ms = ast_remaining_ms ( start , timeout_ms ) ) ) {
int break_loop = 0 ;
2010-04-26 14:18:15 +00:00
ms = ast_waitfor ( chan , ms ) ;
if ( ms < 0 ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " error on '%s' while waiting for T.38 negotiation. \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
}
if ( ms = = 0 ) { /* all done, nothing happened */
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " channel '%s' timed-out during the T.38 negotiation. \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
details - > caps & = ~ AST_FAX_TECH_T38 ;
break ;
}
if ( ! ( frame = ast_read ( chan ) ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " error on '%s' while waiting for T.38 negotiation. \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
}
if ( ( frame - > frametype = = AST_FRAME_CONTROL ) & &
( frame - > subclass . integer = = AST_CONTROL_T38_PARAMETERS ) & &
( frame - > datalen = = sizeof ( t38_parameters ) ) ) {
struct ast_control_t38_parameters * parameters = frame - > data . ptr ;
switch ( parameters - > request_response ) {
case AST_T38_REQUEST_NEGOTIATE :
t38_parameters_fax_to_ast ( & t38_parameters , & details - > our_t38_parameters ) ;
t38_parameters . request_response = AST_T38_NEGOTIATED ;
ast_indicate_data ( chan , AST_CONTROL_T38_PARAMETERS , & t38_parameters , sizeof ( t38_parameters ) ) ;
break ;
case AST_T38_NEGOTIATED :
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " Negotiated T.38 for receive on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
t38_parameters_ast_to_fax ( & details - > their_t38_parameters , parameters ) ;
details - > caps & = ~ AST_FAX_TECH_AUDIO ;
report_fax_status ( chan , details , " T.38 Negotiated " ) ;
2012-11-07 19:15:26 +00:00
break_loop = 1 ;
2010-04-26 14:18:15 +00:00
break ;
case AST_T38_REFUSED :
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " channel '%s' refused to negotiate T.38 \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
details - > caps & = ~ AST_FAX_TECH_T38 ;
2012-11-07 19:15:26 +00:00
break_loop = 1 ;
2010-04-26 14:18:15 +00:00
break ;
default :
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " channel '%s' failed to negotiate T.38 \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
details - > caps & = ~ AST_FAX_TECH_T38 ;
2012-11-07 19:15:26 +00:00
break_loop = 1 ;
2010-04-26 14:18:15 +00:00
break ;
}
}
ast_frfree ( frame ) ;
2012-11-07 19:15:26 +00:00
if ( break_loop ) {
break ;
}
2010-04-26 14:18:15 +00:00
}
/* if T.38 was negotiated, we are done initializing */
if ( ast_channel_get_t38_state ( chan ) = = T38_STATE_NEGOTIATED ) {
return 0 ;
}
/* send one more CNG tone to get audio going again for some
* carriers if we are going to fall back to audio mode */
if ( details - > option . allow_audio = = AST_FAX_OPTFLAG_TRUE ) {
if ( ast_playtones_start ( chan , 1024 , " !1100/500,!0/3000 " , 1 ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error generating second CNG tone on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
}
2012-11-07 19:15:26 +00:00
timeout_ms = 3500 ;
start = ast_tvnow ( ) ;
while ( ( ms = ast_remaining_ms ( start , timeout_ms ) ) ) {
int break_loop = 0 ;
2010-04-26 14:18:15 +00:00
ms = ast_waitfor ( chan , ms ) ;
if ( ms < 0 ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error while generating second CNG tone on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
ast_playtones_stop ( chan ) ;
return - 1 ;
}
if ( ms = = 0 ) { /* all done, nothing happened */
break ;
}
if ( ! ( frame = ast_read ( chan ) ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error reading frame while generating second CNG tone on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
ast_playtones_stop ( chan ) ;
return - 1 ;
}
if ( ( frame - > frametype = = AST_FRAME_CONTROL ) & &
( frame - > subclass . integer = = AST_CONTROL_T38_PARAMETERS ) & &
( frame - > datalen = = sizeof ( t38_parameters ) ) ) {
struct ast_control_t38_parameters * parameters = frame - > data . ptr ;
switch ( parameters - > request_response ) {
case AST_T38_REQUEST_NEGOTIATE :
/* the other end has requested a switch to T.38, so reply that we are willing, if we can
* do T .38 as well
*/
t38_parameters_fax_to_ast ( & t38_parameters , & details - > our_t38_parameters ) ;
t38_parameters . request_response = ( details - > caps & AST_FAX_TECH_T38 ) ? AST_T38_NEGOTIATED : AST_T38_REFUSED ;
ast_indicate_data ( chan , AST_CONTROL_T38_PARAMETERS , & t38_parameters , sizeof ( t38_parameters ) ) ;
ast_playtones_stop ( chan ) ;
break ;
case AST_T38_NEGOTIATED :
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " Negotiated T.38 for send on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
t38_parameters_ast_to_fax ( & details - > their_t38_parameters , parameters ) ;
details - > caps & = ~ AST_FAX_TECH_AUDIO ;
report_fax_status ( chan , details , " T.38 Negotiated " ) ;
2012-11-07 19:15:26 +00:00
break_loop = 1 ;
2010-04-26 14:18:15 +00:00
break ;
default :
break ;
}
}
ast_frfree ( frame ) ;
2012-11-07 19:15:26 +00:00
if ( break_loop ) {
break ;
}
2010-04-26 14:18:15 +00:00
}
ast_playtones_stop ( chan ) ;
/* if T.38 was negotiated, we are done initializing */
if ( ast_channel_get_t38_state ( chan ) = = T38_STATE_NEGOTIATED ) {
return 0 ;
}
}
}
/* if we made it here, then T.38 failed, check the 'f' flag */
if ( details - > option . allow_audio = = AST_FAX_OPTFLAG_FALSE ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " Audio FAX not allowed on channel '%s' and T.38 negotiation failed; aborting. \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
}
/* ok, audio fallback is allowed */
details - > caps | = AST_FAX_TECH_AUDIO ;
return 0 ;
}
2013-05-24 20:44:07 +00:00
/*!
* \ brief Report on the status of a completed fax send attempt
* \ note This will lock the \ ref ast_channel
*/
static int report_send_fax_status ( struct ast_channel * chan , struct ast_fax_session_details * details )
{
2013-05-26 04:47:17 +00:00
RAII_VAR ( struct ast_json * , json_obj , NULL , ast_json_unref ) ;
2013-05-24 20:44:07 +00:00
RAII_VAR ( struct stasis_message * , message , NULL , ao2_cleanup ) ;
struct ast_json * json_filenames ;
json_filenames = generate_filenames_json ( details ) ;
if ( ! json_filenames ) {
return - 1 ;
}
{
2013-06-22 13:58:07 +00:00
const char * remote_station_id ;
const char * local_station_id ;
const char * fax_pages ;
const char * fax_resolution ;
const char * fax_bitrate ;
2013-05-24 20:44:07 +00:00
SCOPED_CHANNELLOCK ( lock , chan ) ;
2013-06-22 13:58:07 +00:00
remote_station_id = S_OR ( pbx_builtin_getvar_helper ( chan , " REMOTESTATIONID " ) , " " ) ;
2013-06-22 22:42:34 +00:00
if ( ! ast_strlen_zero ( remote_station_id ) ) {
remote_station_id = ast_strdupa ( remote_station_id ) ;
}
2013-06-22 13:58:07 +00:00
local_station_id = S_OR ( pbx_builtin_getvar_helper ( chan , " LOCALSTATIONID " ) , " " ) ;
2013-06-22 22:42:34 +00:00
if ( ! ast_strlen_zero ( local_station_id ) ) {
local_station_id = ast_strdupa ( local_station_id ) ;
}
2013-06-22 13:58:07 +00:00
fax_pages = S_OR ( pbx_builtin_getvar_helper ( chan , " FAXPAGES " ) , " " ) ;
2013-06-22 22:42:34 +00:00
if ( ! ast_strlen_zero ( fax_pages ) ) {
fax_pages = ast_strdupa ( fax_pages ) ;
}
2013-06-22 13:58:07 +00:00
fax_resolution = S_OR ( pbx_builtin_getvar_helper ( chan , " FAXRESOLUTION " ) , " " ) ;
2013-06-22 22:42:34 +00:00
if ( ! ast_strlen_zero ( fax_resolution ) ) {
fax_resolution = ast_strdupa ( fax_resolution ) ;
}
2013-06-22 13:58:07 +00:00
fax_bitrate = S_OR ( pbx_builtin_getvar_helper ( chan , " FAXBITRATE " ) , " " ) ;
2013-06-22 22:42:34 +00:00
if ( ! ast_strlen_zero ( fax_bitrate ) ) {
fax_bitrate = ast_strdupa ( fax_bitrate ) ;
}
2013-05-26 04:47:17 +00:00
json_obj = ast_json_pack ( " {s: s, s: s, s: s, s: s, s: s, s: s, s: o} " ,
2013-06-23 19:19:30 +00:00
" type " , " send " ,
2013-06-22 22:42:34 +00:00
" remote_station_id " , S_OR ( remote_station_id , " " ) ,
" local_station_id " , S_OR ( local_station_id , " " ) ,
" fax_pages " , S_OR ( fax_pages , " " ) ,
" fax_resolution " , S_OR ( fax_resolution , " " ) ,
" fax_bitrate " , S_OR ( fax_bitrate , " " ) ,
2013-05-24 20:44:07 +00:00
" filenames " , json_filenames ) ;
if ( ! json_obj ) {
return - 1 ;
}
2013-05-29 02:26:17 +00:00
message = ast_channel_blob_create_from_cache ( ast_channel_uniqueid ( chan ) , ast_channel_fax_type ( ) , json_obj ) ;
2013-05-24 20:44:07 +00:00
if ( ! message ) {
return - 1 ;
}
stasis_publish ( ast_channel_topic ( chan ) , message ) ;
}
return 0 ;
}
2010-04-26 14:18:15 +00:00
2010-03-02 23:11:06 +00:00
/*! \brief initiate a send FAX session */
static int sendfax_exec ( struct ast_channel * chan , const char * data )
{
2010-08-09 14:52:21 +00:00
char * parse , * filenames , * c , modems [ 128 ] = " " ;
2010-06-25 19:42:54 +00:00
int channel_alive , file_count ;
2013-05-27 01:33:12 +00:00
RAII_VAR ( struct ast_fax_session_details * , details , NULL , ao2_cleanup ) ;
RAII_VAR ( struct ast_fax_session * , s , NULL , ao2_cleanup ) ;
2011-01-26 19:58:14 +00:00
struct ast_fax_tech_token * token = NULL ;
2010-03-02 23:11:06 +00:00
struct ast_fax_document * doc ;
AST_DECLARE_APP_ARGS ( args ,
2010-06-25 19:42:54 +00:00
AST_APP_ARG ( filenames ) ;
2010-03-02 23:11:06 +00:00
AST_APP_ARG ( options ) ;
) ;
struct ast_flags opts = { 0 , } ;
2011-05-16 14:56:53 +00:00
enum ast_t38_state t38state ;
2010-03-02 23:11:06 +00:00
2010-07-20 21:01:26 +00:00
/* initialize output channel variables */
pbx_builtin_setvar_helper ( chan , " FAXSTATUS " , " FAILED " ) ;
pbx_builtin_setvar_helper ( chan , " REMOTESTATIONID " , NULL ) ;
pbx_builtin_setvar_helper ( chan , " FAXPAGES " , " 0 " ) ;
pbx_builtin_setvar_helper ( chan , " FAXBITRATE " , NULL ) ;
pbx_builtin_setvar_helper ( chan , " FAXRESOLUTION " , NULL ) ;
2010-07-07 16:40:19 +00:00
/* Get a requirement structure and set it. This structure is used
* to tell the FAX technology module about the higher level FAX session */
if ( ! ( details = find_or_create_details ( chan ) ) ) {
2010-07-20 21:01:26 +00:00
pbx_builtin_setvar_helper ( chan , " FAXERROR " , " MEMORY_ERROR " ) ;
pbx_builtin_setvar_helper ( chan , " FAXSTATUSSTRING " , " error allocating memory " ) ;
2010-07-07 16:40:19 +00:00
ast_log ( LOG_ERROR , " System cannot provide memory for session requirements. \n " ) ;
return - 1 ;
}
2010-08-04 15:22:02 +00:00
ast_string_field_set ( details , result , " FAILED " ) ;
ast_string_field_set ( details , resultstr , " error starting fax session " ) ;
ast_string_field_set ( details , error , " INIT_ERROR " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2011-10-05 06:40:40 +00:00
if ( details - > gateway_id > 0 ) {
2011-06-30 18:22:28 +00:00
ast_string_field_set ( details , resultstr , " can't send a fax on a channel with a T.38 gateway " ) ;
set_channel_variables ( chan , details ) ;
ast_log ( LOG_ERROR , " executing SendFAX on a channel with a T.38 Gateway is not supported \n " ) ;
return - 1 ;
}
2010-08-09 14:52:21 +00:00
if ( details - > maxrate < details - > minrate ) {
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " maxrate is less than minrate " ) ;
set_channel_variables ( chan , details ) ;
2014-05-09 22:49:26 +00:00
ast_log ( LOG_ERROR , " maxrate %u is less than minrate %u \n " , details - > maxrate , details - > minrate ) ;
2010-08-09 14:52:21 +00:00
return - 1 ;
}
if ( check_modem_rate ( details - > modems , details - > minrate ) ) {
ast_fax_modem_to_str ( details - > modems , modems , sizeof ( modems ) ) ;
2014-05-09 22:49:26 +00:00
ast_log ( LOG_ERROR , " 'modems' setting '%s' is incompatible with 'minrate' setting %u \n " , modems , details - > minrate ) ;
2010-08-09 14:52:21 +00:00
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " incompatible 'modems' and 'minrate' settings " ) ;
set_channel_variables ( chan , details ) ;
return - 1 ;
}
if ( check_modem_rate ( details - > modems , details - > maxrate ) ) {
ast_fax_modem_to_str ( details - > modems , modems , sizeof ( modems ) ) ;
2014-05-09 22:49:26 +00:00
ast_log ( LOG_ERROR , " 'modems' setting '%s' is incompatible with 'maxrate' setting %u \n " , modems , details - > maxrate ) ;
2010-08-09 14:52:21 +00:00
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " incompatible 'modems' and 'maxrate' settings " ) ;
set_channel_variables ( chan , details ) ;
return - 1 ;
}
2010-03-02 23:11:06 +00:00
if ( ast_strlen_zero ( data ) ) {
2010-07-07 16:40:19 +00:00
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " invalid arguments " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2010-06-25 19:42:54 +00:00
ast_log ( LOG_WARNING , " %s requires an argument (filename[&filename[&filename]][,options]) \n " , app_sendfax ) ;
2010-03-02 23:11:06 +00:00
return - 1 ;
}
parse = ast_strdupa ( data ) ;
AST_STANDARD_APP_ARGS ( args , parse ) ;
if ( ! ast_strlen_zero ( args . options ) & &
2013-05-27 01:33:12 +00:00
ast_app_parse_options ( fax_exec_options , & opts , NULL , args . options ) ) {
2010-07-20 21:01:26 +00:00
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " invalid arguments " ) ;
set_channel_variables ( chan , details ) ;
2010-03-02 23:11:06 +00:00
return - 1 ;
}
2010-06-25 19:42:54 +00:00
if ( ast_strlen_zero ( args . filenames ) ) {
2010-07-07 16:40:19 +00:00
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " invalid arguments " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2010-06-25 19:42:54 +00:00
ast_log ( LOG_WARNING , " %s requires an argument (filename[&filename[&filename]],options]) \n " , app_sendfax ) ;
2010-03-02 23:11:06 +00:00
return - 1 ;
}
2011-12-28 18:59:16 +00:00
2010-03-02 23:11:06 +00:00
/* check for unsupported FAX application options */
if ( ast_test_flag ( & opts , OPT_CALLERMODE ) | | ast_test_flag ( & opts , OPT_CALLEDMODE ) ) {
2010-07-07 16:40:19 +00:00
ast_string_field_set ( details , error , " INVALID_ARGUMENTS " ) ;
ast_string_field_set ( details , resultstr , " invalid arguments " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2010-03-02 23:11:06 +00:00
ast_log ( LOG_WARNING , " %s does not support polling \n " , app_sendfax ) ;
return - 1 ;
}
ast_atomic_fetchadd_int ( & faxregistry . fax_tx_attempts , 1 ) ;
2010-06-25 19:42:54 +00:00
file_count = 0 ;
filenames = args . filenames ;
while ( ( c = strsep ( & filenames , " & " ) ) ) {
if ( access ( c , ( F_OK | R_OK ) ) < 0 ) {
2010-07-07 16:40:19 +00:00
ast_string_field_set ( details , error , " FILE_ERROR " ) ;
ast_string_field_set ( details , resultstr , " error reading file " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2010-06-25 19:42:54 +00:00
ast_log ( LOG_ERROR , " access failure. Verify '%s' exists and check permissions. \n " , args . filenames ) ;
return - 1 ;
}
if ( ! ( doc = ast_calloc ( 1 , sizeof ( * doc ) + strlen ( c ) + 1 ) ) ) {
2010-07-07 16:40:19 +00:00
ast_string_field_set ( details , error , " MEMORY_ERROR " ) ;
ast_string_field_set ( details , resultstr , " error allocating memory " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2010-06-25 19:42:54 +00:00
ast_log ( LOG_ERROR , " System cannot provide memory for session requirements. \n " ) ;
return - 1 ;
}
strcpy ( doc - > filename , c ) ;
AST_LIST_INSERT_TAIL ( & details - > documents , doc , next ) ;
file_count + + ;
2010-03-02 23:11:06 +00:00
}
2012-01-09 22:15:50 +00:00
ast_verb ( 3 , " Channel '%s' sending FAX: \n " , ast_channel_name ( chan ) ) ;
2010-06-25 19:42:54 +00:00
AST_LIST_TRAVERSE ( & details - > documents , doc , next ) {
ast_verb ( 3 , " %s \n " , doc - > filename ) ;
}
2010-03-02 23:11:06 +00:00
details - > caps = AST_FAX_TECH_SEND ;
2011-10-03 15:42:01 +00:00
if ( file_count > 1 ) {
details - > caps | = AST_FAX_TECH_MULTI_DOC ;
}
2010-03-02 23:11:06 +00:00
/* check for debug */
if ( ast_test_flag ( & opts , OPT_DEBUG ) | | global_fax_debug ) {
details - > option . debug = AST_FAX_OPTFLAG_TRUE ;
}
/* check for request for status events */
if ( ast_test_flag ( & opts , OPT_STATUS ) ) {
details - > option . statusevents = AST_FAX_OPTFLAG_TRUE ;
}
2011-05-16 14:56:53 +00:00
t38state = ast_channel_get_t38_state ( chan ) ;
if ( ( t38state = = T38_STATE_UNAVAILABLE ) | | ( t38state = = T38_STATE_REJECTED ) | |
2011-01-26 22:39:07 +00:00
ast_test_flag ( & opts , OPT_ALLOWAUDIO ) | |
2011-01-27 15:57:52 +00:00
ast_test_flag ( & opts , OPT_FORCE_AUDIO ) ) {
2010-03-02 23:11:06 +00:00
details - > option . allow_audio = AST_FAX_OPTFLAG_TRUE ;
}
2010-04-26 14:18:15 +00:00
if ( ast_test_flag ( & opts , OPT_REQUEST_T38 ) ) {
details - > option . request_t38 = AST_FAX_OPTFLAG_TRUE ;
}
2011-01-26 19:58:14 +00:00
if ( ! ( s = fax_session_reserve ( details , & token ) ) ) {
2010-12-03 15:32:22 +00:00
ast_string_field_set ( details , resultstr , " error reserving fax session " ) ;
set_channel_variables ( chan , details ) ;
ast_log ( LOG_ERROR , " Unable to reserve FAX session. \n " ) ;
return - 1 ;
}
/* make sure the channel is up */
2012-02-20 23:43:27 +00:00
if ( ast_channel_state ( chan ) ! = AST_STATE_UP ) {
2010-12-03 15:32:22 +00:00
if ( ast_answer ( chan ) ) {
ast_string_field_set ( details , resultstr , " error answering channel " ) ;
set_channel_variables ( chan , details ) ;
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " Channel '%s' failed answer attempt. \n " , ast_channel_name ( chan ) ) ;
2011-01-26 19:58:14 +00:00
fax_session_release ( s , token ) ;
2010-12-03 15:32:22 +00:00
return - 1 ;
}
}
2011-01-27 15:57:52 +00:00
if ( ! ast_test_flag ( & opts , OPT_FORCE_AUDIO ) ) {
2011-01-26 22:39:07 +00:00
if ( set_fax_t38_caps ( chan , details ) ) {
ast_string_field_set ( details , error , " T38_NEG_ERROR " ) ;
ast_string_field_set ( details , resultstr , " error negotiating T.38 " ) ;
set_channel_variables ( chan , details ) ;
fax_session_release ( s , token ) ;
return - 1 ;
}
2011-01-27 20:07:05 +00:00
} else {
details - > caps | = AST_FAX_TECH_AUDIO ;
2010-04-26 14:18:15 +00:00
}
2011-01-27 15:57:52 +00:00
if ( ! ast_test_flag ( & opts , OPT_FORCE_AUDIO ) & & ( details - > caps & AST_FAX_TECH_T38 ) ) {
2010-04-26 14:18:15 +00:00
if ( sendfax_t38_init ( chan , details ) ) {
2010-07-07 16:40:19 +00:00
ast_string_field_set ( details , error , " T38_NEG_ERROR " ) ;
ast_string_field_set ( details , resultstr , " error negotiating T.38 " ) ;
2010-07-20 21:01:26 +00:00
set_channel_variables ( chan , details ) ;
2011-01-26 19:58:14 +00:00
fax_session_release ( s , token ) ;
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error initializing channel '%s' in T.38 mode \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
return - 1 ;
}
} else {
details - > option . send_cng = 1 ;
}
2011-01-26 19:58:14 +00:00
if ( ( channel_alive = generic_fax_exec ( chan , details , s , token ) ) < 0 ) {
2010-03-02 23:11:06 +00:00
ast_atomic_fetchadd_int ( & faxregistry . fax_failures , 1 ) ;
}
2010-04-26 14:18:15 +00:00
if ( ast_channel_get_t38_state ( chan ) = = T38_STATE_NEGOTIATED ) {
if ( disable_t38 ( chan ) ) {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " error disabling T.38 mode on %s \n " , ast_channel_name ( chan ) ) ;
2010-04-26 14:18:15 +00:00
}
}
2010-06-25 19:42:54 +00:00
if ( ! ( filenames = generate_filenames_string ( details , " FileName: " , " \r \n " ) ) ) {
ast_log ( LOG_ERROR , " Error generating SendFAX manager event \n " ) ;
return ( ! channel_alive ) ? - 1 : 0 ;
}
2010-03-02 23:11:06 +00:00
/* send out the AMI completion event */
2013-05-24 20:44:07 +00:00
if ( report_send_fax_status ( chan , details ) ) {
ast_log ( AST_LOG_ERROR , " Error publishing SendFAX status message \n " ) ;
}
2010-03-02 23:11:06 +00:00
/* If the channel hungup return -1; otherwise, return 0 to continue in the dialplan */
return ( ! channel_alive ) ? - 1 : 0 ;
}
2011-12-28 18:59:16 +00:00
/*! \brief destroy the v21 detection parts of a fax gateway session */
static void destroy_v21_sessions ( struct fax_gateway * gateway )
2011-06-30 18:22:28 +00:00
{
2011-12-28 18:59:16 +00:00
if ( gateway - > chan_v21_session ) {
ao2_unlink ( faxregistry . container , gateway - > chan_v21_session ) ;
2011-06-30 18:22:28 +00:00
2011-12-28 18:59:16 +00:00
ao2_ref ( gateway - > chan_v21_session , - 1 ) ;
gateway - > chan_v21_session = NULL ;
2011-06-30 18:22:28 +00:00
}
2011-12-28 18:59:16 +00:00
if ( gateway - > peer_v21_session ) {
ao2_unlink ( faxregistry . container , gateway - > peer_v21_session ) ;
ao2_ref ( gateway - > peer_v21_session , - 1 ) ;
gateway - > peer_v21_session = NULL ;
2011-06-30 18:22:28 +00:00
}
2011-12-28 18:59:16 +00:00
}
/*! \brief destroy a FAX gateway session structure */
static void destroy_gateway ( void * data )
{
struct fax_gateway * gateway = data ;
destroy_v21_sessions ( gateway ) ;
2011-06-30 18:22:28 +00:00
if ( gateway - > s ) {
fax_session_release ( gateway - > s , gateway - > token ) ;
gateway - > token = NULL ;
ao2_unlink ( faxregistry . container , gateway - > s ) ;
ao2_ref ( gateway - > s , - 1 ) ;
gateway - > s = NULL ;
}
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
ao2_cleanup ( gateway - > chan_read_format ) ;
ao2_cleanup ( gateway - > chan_write_format ) ;
ao2_cleanup ( gateway - > peer_read_format ) ;
ao2_cleanup ( gateway - > peer_write_format ) ;
2011-06-30 18:22:28 +00:00
}
/*! \brief Create a new fax gateway object.
2011-12-28 18:59:16 +00:00
* \ param chan the channel the gateway object will be attached to
2011-06-30 18:22:28 +00:00
* \ param details the fax session details
* \ return NULL or a fax gateway object
*/
2011-12-28 18:59:16 +00:00
static struct fax_gateway * fax_gateway_new ( struct ast_channel * chan , struct ast_fax_session_details * details )
2011-06-30 18:22:28 +00:00
{
struct fax_gateway * gateway = ao2_alloc ( sizeof ( * gateway ) , destroy_gateway ) ;
2011-12-28 18:59:16 +00:00
struct ast_fax_session_details * v21_details ;
2011-06-30 18:22:28 +00:00
if ( ! gateway ) {
return NULL ;
}
2011-12-28 18:59:16 +00:00
if ( ! ( v21_details = session_details_new ( ) ) ) {
2011-06-30 18:22:28 +00:00
ao2_ref ( gateway , - 1 ) ;
return NULL ;
}
2011-12-28 18:59:16 +00:00
v21_details - > caps = AST_FAX_TECH_V21_DETECT ;
if ( ! ( gateway - > chan_v21_session = fax_session_new ( v21_details , chan , NULL , NULL ) ) ) {
ao2_ref ( v21_details , - 1 ) ;
2011-06-30 18:22:28 +00:00
ao2_ref ( gateway , - 1 ) ;
return NULL ;
}
2011-12-28 18:59:16 +00:00
if ( ! ( gateway - > peer_v21_session = fax_session_new ( v21_details , chan , NULL , NULL ) ) ) {
ao2_ref ( v21_details , - 1 ) ;
ao2_ref ( gateway , - 1 ) ;
return NULL ;
}
ao2_ref ( v21_details , - 1 ) ;
2011-06-30 18:22:28 +00:00
2011-12-28 18:59:16 +00:00
gateway - > framehook = - 1 ;
2011-06-30 18:22:28 +00:00
details - > caps = AST_FAX_TECH_GATEWAY ;
2011-08-22 16:31:59 +00:00
if ( details - > gateway_timeout & & ! ( gateway - > s = fax_session_reserve ( details , & gateway - > token ) ) ) {
2011-10-03 15:21:50 +00:00
details - > caps & = ~ AST_FAX_TECH_GATEWAY ;
2011-06-30 18:22:28 +00:00
ast_log ( LOG_ERROR , " Can't reserve a FAX session, gateway attempt failed. \n " ) ;
ao2_ref ( gateway , - 1 ) ;
return NULL ;
}
return gateway ;
}
/*! \brief Create a fax session and start T.30<->T.38 gateway mode
* \ param gateway a fax gateway object
* \ param details fax session details
* \ param chan active channel
* \ return 0 on error 1 on success */
static int fax_gateway_start ( struct fax_gateway * gateway , struct ast_fax_session_details * details , struct ast_channel * chan )
{
struct ast_fax_session * s ;
2015-01-20 16:59:30 +00:00
int start_res ;
2011-06-30 18:22:28 +00:00
/* create the FAX session */
if ( ! ( s = fax_session_new ( details , chan , gateway - > s , gateway - > token ) ) ) {
gateway - > token = NULL ;
ast_string_field_set ( details , result , " FAILED " ) ;
ast_string_field_set ( details , resultstr , " error starting gateway session " ) ;
ast_string_field_set ( details , error , " INIT_ERROR " ) ;
set_channel_variables ( chan , details ) ;
report_fax_status ( chan , details , " No Available Resource " ) ;
ast_log ( LOG_ERROR , " Can't create a FAX session, gateway attempt failed. \n " ) ;
return - 1 ;
}
/* release the reference for the reserved session and replace it with
* the real session */
2012-11-04 02:44:35 +00:00
if ( gateway - > s ) {
ao2_ref ( gateway - > s , - 1 ) ;
}
2011-06-30 18:22:28 +00:00
gateway - > s = s ;
gateway - > token = NULL ;
2015-01-20 16:59:30 +00:00
ast_channel_unlock ( chan ) ;
start_res = gateway - > s - > tech - > start_session ( gateway - > s ) ;
ast_channel_lock ( chan ) ;
if ( start_res < 0 ) {
2011-06-30 18:22:28 +00:00
ast_string_field_set ( details , result , " FAILED " ) ;
ast_string_field_set ( details , resultstr , " error starting gateway session " ) ;
ast_string_field_set ( details , error , " INIT_ERROR " ) ;
set_channel_variables ( chan , details ) ;
return - 1 ;
}
gateway - > timeout_start . tv_sec = 0 ;
gateway - > timeout_start . tv_usec = 0 ;
report_fax_status ( chan , details , " FAX Transmission In Progress " ) ;
return 0 ;
}
2011-07-11 17:23:54 +00:00
static struct ast_frame * fax_gateway_request_t38 ( struct fax_gateway * gateway , struct ast_channel * chan , struct ast_frame * f )
2011-07-11 13:29:13 +00:00
{
struct ast_frame * fp ;
struct ast_control_t38_parameters t38_parameters = {
. request_response = AST_T38_REQUEST_NEGOTIATE ,
} ;
struct ast_frame control_frame = {
. src = " res_fax " ,
. frametype = AST_FRAME_CONTROL ,
. datalen = sizeof ( t38_parameters ) ,
. subclass . integer = AST_CONTROL_T38_PARAMETERS ,
. data . ptr = & t38_parameters ,
} ;
struct ast_fax_session_details * details = find_details ( chan ) ;
if ( ! details ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " no FAX session details found on chan %s for T.38 gateway session, odd \n " , ast_channel_name ( chan ) ) ;
2011-07-11 13:29:13 +00:00
ast_framehook_detach ( chan , gateway - > framehook ) ;
return f ;
}
t38_parameters_fax_to_ast ( & t38_parameters , & details - > our_t38_parameters ) ;
ao2_ref ( details , - 1 ) ;
if ( ! ( fp = ast_frisolate ( & control_frame ) ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error generating T.38 request control frame on chan %s for T.38 gateway session \n " , ast_channel_name ( chan ) ) ;
2011-07-11 13:29:13 +00:00
return f ;
}
gateway - > t38_state = T38_STATE_NEGOTIATING ;
gateway - > timeout_start = ast_tvnow ( ) ;
2011-08-22 16:31:59 +00:00
details - > gateway_timeout = FAX_GATEWAY_TIMEOUT ;
2011-07-11 13:29:13 +00:00
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " requesting T.38 for gateway session for %s \n " , ast_channel_name ( chan ) ) ;
2011-07-11 13:29:13 +00:00
return fp ;
}
2011-07-12 15:23:24 +00:00
static struct ast_frame * fax_gateway_detect_v21 ( struct fax_gateway * gateway , struct ast_channel * chan , struct ast_channel * peer , struct ast_channel * active , struct ast_frame * f )
2011-06-30 18:22:28 +00:00
{
struct ast_channel * other = ( active = = chan ) ? peer : chan ;
2011-12-28 18:59:16 +00:00
struct ast_fax_session * active_v21_session = ( active = = chan ) ? gateway - > chan_v21_session : gateway - > peer_v21_session ;
2011-06-30 18:22:28 +00:00
2011-12-28 18:59:16 +00:00
if ( ! active_v21_session | | gateway - > detected_v21 ) {
2011-07-11 16:27:08 +00:00
return f ;
}
2011-12-28 18:59:16 +00:00
if ( active_v21_session - > tech - > write ( active_v21_session , f ) = = 0 & &
active_v21_session - > details - > option . v21_detected ) {
gateway - > detected_v21 = 1 ;
2011-06-30 18:22:28 +00:00
}
2011-12-28 18:59:16 +00:00
if ( gateway - > detected_v21 ) {
destroy_v21_sessions ( gateway ) ;
2011-07-11 16:27:08 +00:00
if ( ast_channel_get_t38_state ( other ) = = T38_STATE_UNKNOWN ) {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " detected v21 preamble from %s \n " , ast_channel_name ( active ) ) ;
2011-07-12 15:23:24 +00:00
return fax_gateway_request_t38 ( gateway , chan , f ) ;
2011-06-30 18:22:28 +00:00
} else {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " detected v21 preamble on %s, but %s does not support T.38 for T.38 gateway session \n " , ast_channel_name ( active ) , ast_channel_name ( other ) ) ;
2011-06-30 18:22:28 +00:00
}
}
return f ;
}
static int fax_gateway_indicate_t38 ( struct ast_channel * chan , struct ast_channel * active , struct ast_control_t38_parameters * control_params )
{
if ( active = = chan ) {
return ast_indicate_data ( chan , AST_CONTROL_T38_PARAMETERS , control_params , sizeof ( * control_params ) ) ;
} else {
return ast_queue_control_data ( chan , AST_CONTROL_T38_PARAMETERS , control_params , sizeof ( * control_params ) ) ;
}
}
/*! \brief T38 Gateway Negotiate t38 parameters
* \ param gateway gateway object
* \ param chan channel running the gateway
* \ param peer channel im bridged too
* \ param active channel the frame originated on
* \ param f the control frame to process
* \ return processed control frame or null frame
*/
static struct ast_frame * fax_gateway_detect_t38 ( struct fax_gateway * gateway , struct ast_channel * chan , struct ast_channel * peer , struct ast_channel * active , struct ast_frame * f )
{
struct ast_control_t38_parameters * control_params = f - > data . ptr ;
struct ast_channel * other = ( active = = chan ) ? peer : chan ;
struct ast_fax_session_details * details ;
if ( f - > datalen ! = sizeof ( struct ast_control_t38_parameters ) ) {
/* invalaid AST_CONTROL_T38_PARAMETERS frame, we can't
* do anything with it , pass it on */
return f ;
}
/* ignore frames from ourselves */
if ( ( gateway - > t38_state = = T38_STATE_NEGOTIATED & & control_params - > request_response = = AST_T38_NEGOTIATED )
| | ( gateway - > t38_state = = T38_STATE_REJECTED & & control_params - > request_response = = AST_T38_REFUSED )
| | ( gateway - > t38_state = = T38_STATE_NEGOTIATING & & control_params - > request_response = = AST_T38_REQUEST_TERMINATE ) ) {
return f ;
}
if ( ! ( details = find_details ( chan ) ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " no FAX session details found on chan %s for T.38 gateway session, odd \n " , ast_channel_name ( chan ) ) ;
2011-06-30 18:22:28 +00:00
ast_framehook_detach ( chan , gateway - > framehook ) ;
return f ;
}
if ( control_params - > request_response = = AST_T38_REQUEST_NEGOTIATE ) {
enum ast_t38_state state = ast_channel_get_t38_state ( other ) ;
2011-07-11 13:29:13 +00:00
2011-06-30 18:22:28 +00:00
if ( state = = T38_STATE_UNKNOWN ) {
/* we detected a request to negotiate T.38 and the
* other channel appears to support T .38 , we ' ll pass
* the request through and only step in if the other
* channel rejects the request */
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " %s is attempting to negotiate T.38 with %s, we'll see what happens \n " , ast_channel_name ( active ) , ast_channel_name ( other ) ) ;
2011-06-30 18:22:28 +00:00
t38_parameters_ast_to_fax ( & details - > their_t38_parameters , control_params ) ;
gateway - > t38_state = T38_STATE_UNKNOWN ;
gateway - > timeout_start = ast_tvnow ( ) ;
2011-08-22 16:31:59 +00:00
details - > gateway_timeout = FAX_GATEWAY_TIMEOUT ;
2011-06-30 18:22:28 +00:00
ao2_ref ( details , - 1 ) ;
return f ;
} else if ( state = = T38_STATE_UNAVAILABLE | | state = = T38_STATE_REJECTED ) {
/* the other channel does not support T.38, we need to
* step in here */
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " %s is attempting to negotiate T.38 but %s does not support it \n " , ast_channel_name ( active ) , ast_channel_name ( other ) ) ;
ast_debug ( 1 , " starting T.38 gateway for T.38 channel %s and G.711 channel %s \n " , ast_channel_name ( active ) , ast_channel_name ( other ) ) ;
2011-06-30 18:22:28 +00:00
t38_parameters_ast_to_fax ( & details - > their_t38_parameters , control_params ) ;
t38_parameters_fax_to_ast ( control_params , & details - > our_t38_parameters ) ;
if ( fax_gateway_start ( gateway , details , chan ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error starting T.38 gateway for T.38 channel %s and G.711 channel %s \n " , ast_channel_name ( active ) , ast_channel_name ( other ) ) ;
2011-06-30 18:22:28 +00:00
gateway - > t38_state = T38_STATE_REJECTED ;
control_params - > request_response = AST_T38_REFUSED ;
ast_framehook_detach ( chan , details - > gateway_id ) ;
details - > gateway_id = - 1 ;
} else {
gateway - > t38_state = T38_STATE_NEGOTIATED ;
control_params - > request_response = AST_T38_NEGOTIATED ;
report_fax_status ( chan , details , " T.38 Negotiated " ) ;
}
fax_gateway_indicate_t38 ( chan , active , control_params ) ;
ao2_ref ( details , - 1 ) ;
return & ast_null_frame ;
} else if ( gateway - > t38_state = = T38_STATE_NEGOTIATING ) {
/* we got a request to negotiate T.38 after we already
2011-07-12 15:23:24 +00:00
* sent one to the other party based on v21 preamble
2011-06-30 18:22:28 +00:00
* detection . We ' ll just pretend we passed this request
* through in the first place . */
t38_parameters_ast_to_fax ( & details - > their_t38_parameters , control_params ) ;
gateway - > t38_state = T38_STATE_UNKNOWN ;
gateway - > timeout_start = ast_tvnow ( ) ;
2011-08-22 16:31:59 +00:00
details - > gateway_timeout = FAX_GATEWAY_TIMEOUT ;
2011-06-30 18:22:28 +00:00
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " %s is attempting to negotiate T.38 after we already sent a negotiation request based on v21 preamble detection \n " , ast_channel_name ( active ) ) ;
2011-06-30 18:22:28 +00:00
ao2_ref ( details , - 1 ) ;
return & ast_null_frame ;
} else if ( gateway - > t38_state = = T38_STATE_NEGOTIATED ) {
/* we got a request to negotiate T.38 after we already
2011-07-12 15:23:24 +00:00
* sent one to the other party based on v21 preamble
2011-06-30 18:22:28 +00:00
* detection and received a response . We need to
* respond to this and shut down the gateway . */
t38_parameters_fax_to_ast ( control_params , & details - > their_t38_parameters ) ;
ast_framehook_detach ( chan , details - > gateway_id ) ;
details - > gateway_id = - 1 ;
control_params - > request_response = AST_T38_NEGOTIATED ;
fax_gateway_indicate_t38 ( chan , active , control_params ) ;
ast_string_field_set ( details , result , " SUCCESS " ) ;
ast_string_field_set ( details , resultstr , " no gateway necessary " ) ;
ast_string_field_set ( details , error , " NATIVE_T38 " ) ;
set_channel_variables ( chan , details ) ;
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " %s is attempting to negotiate T.38 after we already negotiated T.38 with %s, disabling the gateway \n " , ast_channel_name ( active ) , ast_channel_name ( other ) ) ;
2011-06-30 18:22:28 +00:00
ao2_ref ( details , - 1 ) ;
return & ast_null_frame ;
} else {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " %s is attempting to negotiate T.38 while %s is in an unsupported state \n " , ast_channel_name ( active ) , ast_channel_name ( other ) ) ;
2011-06-30 18:22:28 +00:00
ao2_ref ( details , - 1 ) ;
return f ;
}
} else if ( gateway - > t38_state = = T38_STATE_NEGOTIATING
& & control_params - > request_response = = AST_T38_REFUSED ) {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " unable to negotiate T.38 on %s for fax gateway \n " , ast_channel_name ( active ) ) ;
2011-06-30 18:22:28 +00:00
/* our request to negotiate T.38 was refused, if the other
* channel supports T .38 , they might still reinvite and save
* the day . Otherwise disable the gateway . */
if ( ast_channel_get_t38_state ( other ) = = T38_STATE_UNKNOWN ) {
gateway - > t38_state = T38_STATE_UNAVAILABLE ;
} else {
ast_framehook_detach ( chan , details - > gateway_id ) ;
details - > gateway_id = - 1 ;
ast_string_field_set ( details , result , " FAILED " ) ;
ast_string_field_set ( details , resultstr , " unable to negotiate T.38 " ) ;
ast_string_field_set ( details , error , " T38_NEG_ERROR " ) ;
set_channel_variables ( chan , details ) ;
}
ao2_ref ( details , - 1 ) ;
return & ast_null_frame ;
} else if ( gateway - > t38_state = = T38_STATE_NEGOTIATING
& & control_params - > request_response = = AST_T38_NEGOTIATED ) {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " starting T.38 gateway for T.38 channel %s and G.711 channel %s \n " , ast_channel_name ( active ) , ast_channel_name ( other ) ) ;
2011-06-30 18:22:28 +00:00
t38_parameters_ast_to_fax ( & details - > their_t38_parameters , control_params ) ;
if ( fax_gateway_start ( gateway , details , chan ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error starting T.38 gateway for T.38 channel %s and G.711 channel %s \n " , ast_channel_name ( active ) , ast_channel_name ( other ) ) ;
2011-06-30 18:22:28 +00:00
gateway - > t38_state = T38_STATE_NEGOTIATING ;
control_params - > request_response = AST_T38_REQUEST_TERMINATE ;
fax_gateway_indicate_t38 ( chan , active , control_params ) ;
} else {
gateway - > t38_state = T38_STATE_NEGOTIATED ;
report_fax_status ( chan , details , " T.38 Negotiated " ) ;
}
ao2_ref ( details , - 1 ) ;
return & ast_null_frame ;
} else if ( control_params - > request_response = = AST_T38_REFUSED ) {
/* the other channel refused the request to negotiate T.38,
* we ' ll step in here and pretend the request was accepted */
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " %s attempted to negotiate T.38 but %s refused the request \n " , ast_channel_name ( other ) , ast_channel_name ( active ) ) ;
ast_debug ( 1 , " starting T.38 gateway for T.38 channel %s and G.711 channel %s \n " , ast_channel_name ( other ) , ast_channel_name ( active ) ) ;
2011-06-30 18:22:28 +00:00
t38_parameters_fax_to_ast ( control_params , & details - > our_t38_parameters ) ;
if ( fax_gateway_start ( gateway , details , chan ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " error starting T.38 gateway for T.38 channel %s and G.711 channel %s \n " , ast_channel_name ( active ) , ast_channel_name ( other ) ) ;
2011-06-30 18:22:28 +00:00
gateway - > t38_state = T38_STATE_REJECTED ;
control_params - > request_response = AST_T38_REFUSED ;
ast_framehook_detach ( chan , details - > gateway_id ) ;
details - > gateway_id = - 1 ;
} else {
gateway - > t38_state = T38_STATE_NEGOTIATED ;
control_params - > request_response = AST_T38_NEGOTIATED ;
}
ao2_ref ( details , - 1 ) ;
return f ;
} else if ( control_params - > request_response = = AST_T38_REQUEST_TERMINATE ) {
/* the channel wishes to end our short relationship, we shall
* oblige */
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " T.38 channel %s is requesting a shutdown of T.38, disabling the gateway \n " , ast_channel_name ( active ) ) ;
2011-06-30 18:22:28 +00:00
ast_framehook_detach ( chan , details - > gateway_id ) ;
details - > gateway_id = - 1 ;
gateway - > t38_state = T38_STATE_REJECTED ;
control_params - > request_response = AST_T38_TERMINATED ;
fax_gateway_indicate_t38 ( chan , active , control_params ) ;
ao2_ref ( details , - 1 ) ;
return & ast_null_frame ;
} else if ( control_params - > request_response = = AST_T38_NEGOTIATED ) {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " T.38 successfully negotiated between %s and %s, no gateway necessary \n " , ast_channel_name ( active ) , ast_channel_name ( other ) ) ;
2011-06-30 18:22:28 +00:00
ast_framehook_detach ( chan , details - > gateway_id ) ;
details - > gateway_id = - 1 ;
ast_string_field_set ( details , result , " SUCCESS " ) ;
ast_string_field_set ( details , resultstr , " no gateway necessary " ) ;
ast_string_field_set ( details , error , " NATIVE_T38 " ) ;
set_channel_variables ( chan , details ) ;
ao2_ref ( details , - 1 ) ;
return f ;
} else if ( control_params - > request_response = = AST_T38_TERMINATED ) {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " T.38 disabled on channel %s \n " , ast_channel_name ( active ) ) ;
2011-06-30 18:22:28 +00:00
ast_framehook_detach ( chan , details - > gateway_id ) ;
details - > gateway_id = - 1 ;
ao2_ref ( details , - 1 ) ;
return & ast_null_frame ;
}
ao2_ref ( details , - 1 ) ;
return f ;
}
/*! \brief Destroy the gateway data structure when the framehook is detached
* \ param data framehook data ( gateway data ) */
2015-01-15 17:28:51 +00:00
static void fax_gateway_framehook_destroy ( void * data )
{
2011-06-30 18:22:28 +00:00
struct fax_gateway * gateway = data ;
if ( gateway - > s ) {
switch ( gateway - > s - > state ) {
case AST_FAX_STATE_INITIALIZED :
case AST_FAX_STATE_OPEN :
case AST_FAX_STATE_ACTIVE :
case AST_FAX_STATE_COMPLETE :
if ( gateway - > s - > tech - > cancel_session ) {
gateway - > s - > tech - > cancel_session ( gateway - > s ) ;
}
/* fall through */
default :
break ;
}
}
ao2_ref ( gateway , - 1 ) ;
}
/*! \brief T.30<->T.38 gateway framehook.
*
* Intercept packets on bridged channels and determine if a T .38 gateway is
* required . If a gateway is required , start a gateway and handle T .38
* negotiation if necessary .
*
* \ param chan channel running the gateway
* \ param f frame to handle may be NULL
* \ param event framehook event
* \ param data framehook data ( struct fax_gateway * )
*
* \ return processed frame or NULL when f is NULL or a null frame
*/
2015-01-15 17:28:51 +00:00
static struct ast_frame * fax_gateway_framehook ( struct ast_channel * chan , struct ast_frame * f , enum ast_framehook_event event , void * data )
{
2011-06-30 18:22:28 +00:00
struct fax_gateway * gateway = data ;
2013-05-26 16:49:28 +00:00
struct ast_channel * active ;
RAII_VAR ( struct ast_fax_session_details * , details , NULL , ao2_cleanup ) ;
RAII_VAR ( struct ast_channel * , peer , NULL , ao2_cleanup ) ;
2013-06-22 13:58:07 +00:00
RAII_VAR ( struct ast_channel * , chan_ref , chan , ao2_cleanup ) ;
/* Ref bump channel for when we have to unlock it */
ao2_ref ( chan_ref , 1 ) ;
2011-08-22 16:31:59 +00:00
if ( gateway - > s ) {
details = gateway - > s - > details ;
ao2_ref ( details , 1 ) ;
} else {
if ( ! ( details = find_details ( chan ) ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " no FAX session details found on chan %s for T.38 gateway session, odd \n " , ast_channel_name ( chan ) ) ;
2011-08-22 16:31:59 +00:00
ast_framehook_detach ( chan , gateway - > framehook ) ;
return f ;
}
}
2011-06-30 18:22:28 +00:00
/* restore audio formats when we are detached */
if ( event = = AST_FRAMEHOOK_EVENT_DETACHED ) {
2011-08-22 16:31:59 +00:00
set_channel_variables ( chan , details ) ;
2011-06-30 18:22:28 +00:00
if ( gateway - > bridged ) {
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
ast_set_read_format ( chan , gateway - > chan_read_format ) ;
2015-04-17 23:05:37 +00:00
ast_set_write_format ( chan , gateway - > chan_write_format ) ;
2011-06-30 18:22:28 +00:00
2013-06-22 13:58:07 +00:00
ast_channel_unlock ( chan ) ;
peer = ast_channel_bridge_peer ( chan ) ;
if ( peer ) {
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
ast_set_read_format ( peer , gateway - > peer_read_format ) ;
2015-04-17 23:05:37 +00:00
ast_set_write_format ( peer , gateway - > peer_write_format ) ;
2011-06-30 18:22:28 +00:00
ast_channel_make_compatible ( chan , peer ) ;
}
2013-10-18 16:59:09 +00:00
ast_channel_lock ( chan ) ;
2011-06-30 18:22:28 +00:00
}
return NULL ;
}
if ( ! f | | ( event = = AST_FRAMEHOOK_EVENT_ATTACHED ) ) {
return NULL ;
} ;
/* this frame was generated by the fax gateway, pass it on */
if ( ast_test_flag ( f , AST_FAX_FRFLAG_GATEWAY ) ) {
return f ;
}
2013-05-26 16:49:28 +00:00
/* If we aren't bridged or we don't have a peer, don't do anything */
2013-06-22 13:58:07 +00:00
ast_channel_unlock ( chan ) ;
peer = ast_channel_bridge_peer ( chan ) ;
ast_channel_lock ( chan ) ;
if ( ! peer ) {
2011-06-30 18:22:28 +00:00
return f ;
}
2013-10-18 16:59:09 +00:00
if ( ! gateway - > bridged ) {
2011-06-30 18:22:28 +00:00
/* don't start a gateway if neither channel can handle T.38 */
if ( ast_channel_get_t38_state ( chan ) = = T38_STATE_UNAVAILABLE & & ast_channel_get_t38_state ( peer ) = = T38_STATE_UNAVAILABLE ) {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " not starting gateway for %s and %s; neither channel supports T.38 \n " , ast_channel_name ( chan ) , ast_channel_name ( peer ) ) ;
2011-06-30 18:22:28 +00:00
ast_framehook_detach ( chan , gateway - > framehook ) ;
2011-08-22 16:31:59 +00:00
details - > gateway_id = - 1 ;
2011-06-30 18:22:28 +00:00
2011-08-22 16:31:59 +00:00
ast_string_field_set ( details , result , " FAILED " ) ;
ast_string_field_set ( details , resultstr , " neither channel supports T.38 " ) ;
ast_string_field_set ( details , error , " T38_NEG_ERROR " ) ;
set_channel_variables ( chan , details ) ;
2011-06-30 18:22:28 +00:00
return f ;
}
2011-08-22 16:31:59 +00:00
if ( details - > gateway_timeout ) {
gateway - > timeout_start = ast_tvnow ( ) ;
}
2011-06-30 18:22:28 +00:00
2015-04-17 23:05:37 +00:00
ast_channel_unlock ( chan ) ;
ast_channel_lock_both ( chan , peer ) ;
2011-07-12 15:23:24 +00:00
/* we are bridged, change r/w formats to SLIN for v21 preamble
* detection and T .30 */
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
ao2_replace ( gateway - > chan_read_format , ast_channel_readformat ( chan ) ) ;
2015-04-17 23:05:37 +00:00
ao2_replace ( gateway - > chan_write_format , ast_channel_writeformat ( chan ) ) ;
2011-06-30 18:22:28 +00:00
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
ao2_replace ( gateway - > peer_read_format , ast_channel_readformat ( peer ) ) ;
2015-04-17 23:05:37 +00:00
ao2_replace ( gateway - > peer_write_format , ast_channel_writeformat ( peer ) ) ;
2011-06-30 18:22:28 +00:00
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
ast_set_read_format ( chan , ast_format_slin ) ;
ast_set_write_format ( chan , ast_format_slin ) ;
2011-06-30 18:22:28 +00:00
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
ast_set_read_format ( peer , ast_format_slin ) ;
ast_set_write_format ( peer , ast_format_slin ) ;
2011-06-30 18:22:28 +00:00
2015-04-17 23:05:37 +00:00
ast_channel_unlock ( peer ) ;
2011-06-30 18:22:28 +00:00
gateway - > bridged = 1 ;
}
if ( gateway - > bridged & & ! ast_tvzero ( gateway - > timeout_start ) ) {
2011-08-22 16:31:59 +00:00
if ( ast_tvdiff_ms ( ast_tvnow ( ) , gateway - > timeout_start ) > details - > gateway_timeout ) {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " no fax activity between %s and %s after %d ms, disabling gateway \n " , ast_channel_name ( chan ) , ast_channel_name ( peer ) , details - > gateway_timeout ) ;
2011-06-30 18:22:28 +00:00
ast_framehook_detach ( chan , gateway - > framehook ) ;
2011-08-22 16:31:59 +00:00
details - > gateway_id = - 1 ;
2011-06-30 18:22:28 +00:00
2011-08-22 16:31:59 +00:00
ast_string_field_set ( details , result , " FAILED " ) ;
2011-08-30 14:03:02 +00:00
ast_string_field_build ( details , resultstr , " no fax activity after %d ms " , details - > gateway_timeout ) ;
2011-08-22 16:31:59 +00:00
ast_string_field_set ( details , error , " TIMEOUT " ) ;
set_channel_variables ( chan , details ) ;
2011-06-30 18:22:28 +00:00
return f ;
}
}
/* only handle VOICE, MODEM, and CONTROL frames*/
switch ( f - > frametype ) {
case AST_FRAME_VOICE :
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
if ( ( ast_format_cmp ( f - > subclass . format , ast_format_slin ) ! = AST_FORMAT_CMP_EQUAL ) & &
( ast_format_cmp ( f - > subclass . format , ast_format_alaw ) ! = AST_FORMAT_CMP_EQUAL ) & &
( ast_format_cmp ( f - > subclass . format , ast_format_ulaw ) ! = AST_FORMAT_CMP_EQUAL ) ) {
2011-06-30 18:22:28 +00:00
return f ;
}
break ;
case AST_FRAME_MODEM :
if ( f - > subclass . integer = = AST_MODEM_T38 ) {
break ;
}
return f ;
case AST_FRAME_CONTROL :
if ( f - > subclass . integer = = AST_CONTROL_T38_PARAMETERS ) {
break ;
}
return f ;
default :
return f ;
}
/* detect the active channel */
switch ( event ) {
case AST_FRAMEHOOK_EVENT_WRITE :
active = peer ;
break ;
case AST_FRAMEHOOK_EVENT_READ :
active = chan ;
break ;
default :
2014-05-09 22:49:26 +00:00
ast_log ( LOG_WARNING , " unhandled framehook event %u \n " , event ) ;
2011-06-30 18:22:28 +00:00
return f ;
}
/* handle control frames */
if ( f - > frametype = = AST_FRAME_CONTROL & & f - > subclass . integer = = AST_CONTROL_T38_PARAMETERS ) {
return fax_gateway_detect_t38 ( gateway , chan , peer , active , f ) ;
}
2011-07-12 15:23:24 +00:00
if ( ! gateway - > detected_v21 & & gateway - > t38_state = = T38_STATE_UNAVAILABLE & & f - > frametype = = AST_FRAME_VOICE ) {
/* not in gateway mode and have not detected v21 yet, listen
* for v21 */
return fax_gateway_detect_v21 ( gateway , chan , peer , active , f ) ;
2011-07-11 13:29:13 +00:00
}
2011-06-30 18:22:28 +00:00
/* in gateway mode, gateway some packets */
if ( gateway - > t38_state = = T38_STATE_NEGOTIATED ) {
2014-10-28 21:10:42 +00:00
struct ast_trans_pvt * readtrans ;
2011-06-30 18:22:28 +00:00
/* framehooks are called in __ast_read() before frame format
2011-07-11 12:58:50 +00:00
* translation is done , so we need to translate here */
2014-10-28 21:10:42 +00:00
if ( ( f - > frametype = = AST_FRAME_VOICE ) & & ( ast_format_cmp ( f - > subclass . format , ast_format_slin ) ! = AST_FORMAT_CMP_EQUAL )
& & ( readtrans = ast_channel_readtrans ( active ) ) ) {
if ( ( f = ast_translate ( readtrans , f , 1 ) ) = = NULL ) {
2011-06-30 18:22:28 +00:00
f = & ast_null_frame ;
return f ;
}
2014-10-28 21:10:42 +00:00
/* XXX we ignore the return value here, perhaps we should
* disable the gateway if a write fails . I am not sure how a
* write would fail , or even if a failure would be fatal so for
* now we ' ll just ignore the return value . */
gateway - > s - > tech - > write ( gateway - > s , f ) ;
2012-01-05 23:58:26 +00:00
ast_frfree ( f ) ;
2014-10-28 21:10:42 +00:00
} else {
gateway - > s - > tech - > write ( gateway - > s , f ) ;
2012-01-05 23:58:26 +00:00
}
2014-10-28 21:10:42 +00:00
2011-06-30 18:22:28 +00:00
f = & ast_null_frame ;
return f ;
}
2011-07-11 13:29:13 +00:00
/* force silence on the line if T.38 negotiation might be taking place */
2011-07-12 15:23:24 +00:00
if ( gateway - > t38_state ! = T38_STATE_UNAVAILABLE & & gateway - > t38_state ! = T38_STATE_REJECTED ) {
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
if ( f - > frametype = = AST_FRAME_VOICE & &
( ast_format_cmp ( f - > subclass . format , ast_format_slin ) = = AST_FORMAT_CMP_EQUAL ) ) {
2011-07-11 14:13:24 +00:00
short silence_buf [ f - > samples ] ;
struct ast_frame silence_frame = {
. frametype = AST_FRAME_VOICE ,
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
. subclass . format = ast_format_slin ,
2011-07-11 14:13:24 +00:00
. data . ptr = silence_buf ,
. samples = f - > samples ,
. datalen = sizeof ( silence_buf ) ,
} ;
memset ( silence_buf , 0 , sizeof ( silence_buf ) ) ;
return ast_frisolate ( & silence_frame ) ;
} else {
return & ast_null_frame ;
}
2011-07-11 13:29:13 +00:00
}
2011-06-30 18:22:28 +00:00
return f ;
}
/*! \brief Attach a gateway framehook object to a channel.
* \ param chan the channel to attach to
* \ param details fax session details
* \ return the framehook id of the attached framehook or - 1 on error
* \ retval - 1 error
*/
static int fax_gateway_attach ( struct ast_channel * chan , struct ast_fax_session_details * details )
{
struct fax_gateway * gateway ;
struct ast_framehook_interface fr_hook = {
. version = AST_FRAMEHOOK_INTERFACE_VERSION ,
. event_cb = fax_gateway_framehook ,
. destroy_cb = fax_gateway_framehook_destroy ,
2014-07-18 16:28:10 +00:00
. disable_inheritance = 1 , /* Masquerade inheritance is handled through the datastore fixup */
2011-06-30 18:22:28 +00:00
} ;
ast_string_field_set ( details , result , " SUCCESS " ) ;
ast_string_field_set ( details , resultstr , " gateway operation started successfully " ) ;
ast_string_field_set ( details , error , " NO_ERROR " ) ;
set_channel_variables ( chan , details ) ;
/* set up the frame hook*/
2011-12-28 18:59:16 +00:00
gateway = fax_gateway_new ( chan , details ) ;
2011-06-30 18:22:28 +00:00
if ( ! gateway ) {
ast_string_field_set ( details , result , " FAILED " ) ;
ast_string_field_set ( details , resultstr , " error initializing gateway session " ) ;
ast_string_field_set ( details , error , " INIT_ERROR " ) ;
set_channel_variables ( chan , details ) ;
report_fax_status ( chan , details , " No Available Resource " ) ;
return - 1 ;
}
fr_hook . data = gateway ;
ast_channel_lock ( chan ) ;
gateway - > framehook = ast_framehook_attach ( chan , & fr_hook ) ;
ast_channel_unlock ( chan ) ;
if ( gateway - > framehook < 0 ) {
ao2_ref ( gateway , - 1 ) ;
ast_string_field_set ( details , result , " FAILED " ) ;
ast_string_field_set ( details , resultstr , " error attaching gateway to channel " ) ;
ast_string_field_set ( details , error , " INIT_ERROR " ) ;
set_channel_variables ( chan , details ) ;
return - 1 ;
}
return gateway - > framehook ;
}
2011-10-05 06:50:18 +00:00
/*! \brief destroy a FAX detect structure */
static void destroy_faxdetect ( void * data )
{
struct fax_detect * faxdetect = data ;
if ( faxdetect - > dsp ) {
ast_dsp_free ( faxdetect - > dsp ) ;
faxdetect - > dsp = NULL ;
}
ao2_ref ( faxdetect - > details , - 1 ) ;
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
ao2_cleanup ( faxdetect - > orig_format ) ;
2011-10-05 06:50:18 +00:00
}
/*! \brief Create a new fax detect object.
* \ param chan the channel attaching to
* \ param timeout remove framehook in this time if set
* \ param flags required options
* \ return NULL or a fax gateway object
*/
static struct fax_detect * fax_detect_new ( struct ast_channel * chan , int timeout , int flags )
{
struct fax_detect * faxdetect = ao2_alloc ( sizeof ( * faxdetect ) , destroy_faxdetect ) ;
if ( ! faxdetect ) {
return NULL ;
}
faxdetect - > flags = flags ;
if ( timeout ) {
faxdetect - > timeout_start = ast_tvnow ( ) ;
} else {
faxdetect - > timeout_start . tv_sec = 0 ;
faxdetect - > timeout_start . tv_usec = 0 ;
}
if ( faxdetect - > flags & FAX_DETECT_MODE_CNG ) {
faxdetect - > dsp = ast_dsp_new ( ) ;
if ( ! faxdetect - > dsp ) {
ao2_ref ( faxdetect , - 1 ) ;
return NULL ;
}
ast_dsp_set_features ( faxdetect - > dsp , DSP_FEATURE_FAX_DETECT ) ;
ast_dsp_set_faxmode ( faxdetect - > dsp , DSP_FAXMODE_DETECT_CNG | DSP_FAXMODE_DETECT_SQUELCH ) ;
} else {
faxdetect - > dsp = NULL ;
}
return faxdetect ;
}
/*! \brief Deref the faxdetect data structure when the faxdetect framehook is detached
* \ param data framehook data ( faxdetect data ) */
2015-01-15 17:28:51 +00:00
static void fax_detect_framehook_destroy ( void * data )
{
2011-10-05 06:50:18 +00:00
struct fax_detect * faxdetect = data ;
ao2_ref ( faxdetect , - 1 ) ;
}
/*! \brief Fax Detect Framehook
*
* Listen for fax tones in audio path and enable jumping to a extension when detected .
*
* \ param chan channel
* \ param f frame to handle may be NULL
* \ param event framehook event
* \ param data framehook data ( struct fax_detect * )
*
* \ return processed frame or NULL when f is NULL or a null frame
*/
2015-01-15 17:28:51 +00:00
static struct ast_frame * fax_detect_framehook ( struct ast_channel * chan , struct ast_frame * f , enum ast_framehook_event event , void * data )
{
2011-10-05 06:50:18 +00:00
struct fax_detect * faxdetect = data ;
struct ast_fax_session_details * details ;
struct ast_control_t38_parameters * control_params ;
2013-05-26 16:49:28 +00:00
RAII_VAR ( struct ast_channel * , peer , NULL , ao2_cleanup ) ;
2013-06-22 13:58:07 +00:00
RAII_VAR ( struct ast_channel * , chan_ref , chan , ao2_cleanup ) ;
2011-10-05 06:50:18 +00:00
int result = 0 ;
2013-06-22 13:58:07 +00:00
/* Ref bump the channel for when we have to unlock it */
ao2_ref ( chan , 1 ) ;
2011-10-05 06:50:18 +00:00
details = faxdetect - > details ;
switch ( event ) {
case AST_FRAMEHOOK_EVENT_ATTACHED :
/* Setup format for DSP on ATTACH*/
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
ao2_replace ( faxdetect - > orig_format , ast_channel_readformat ( chan ) ) ;
if ( ( ast_format_cmp ( ast_channel_readformat ( chan ) , ast_format_slin ) ! = AST_FORMAT_CMP_EQUAL ) & &
( ast_format_cmp ( ast_channel_readformat ( chan ) , ast_format_alaw ) ! = AST_FORMAT_CMP_EQUAL ) & &
( ast_format_cmp ( ast_channel_readformat ( chan ) , ast_format_ulaw ) ! = AST_FORMAT_CMP_EQUAL ) ) {
if ( ast_set_read_format ( chan , ast_format_slin ) ) {
ast_framehook_detach ( chan , details - > faxdetect_id ) ;
details - > faxdetect_id = - 1 ;
return f ;
}
2011-10-05 06:50:18 +00:00
}
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
2011-10-05 06:50:18 +00:00
return NULL ;
case AST_FRAMEHOOK_EVENT_DETACHED :
/* restore audio formats when we are detached */
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
ast_set_read_format ( chan , faxdetect - > orig_format ) ;
2013-06-22 13:58:07 +00:00
ast_channel_unlock ( chan ) ;
peer = ast_channel_bridge_peer ( chan ) ;
if ( peer ) {
2011-10-05 06:50:18 +00:00
ast_channel_make_compatible ( chan , peer ) ;
}
2013-10-18 16:59:09 +00:00
ast_channel_lock ( chan ) ;
2011-10-05 06:50:18 +00:00
return NULL ;
case AST_FRAMEHOOK_EVENT_READ :
if ( f ) {
break ;
}
default :
return f ;
} ;
if ( details - > faxdetect_id < 0 ) {
return f ;
}
if ( ( ! ast_tvzero ( faxdetect - > timeout_start ) & &
( ast_tvdiff_ms ( ast_tvnow ( ) , faxdetect - > timeout_start ) > faxdetect - > timeout ) ) ) {
ast_framehook_detach ( chan , details - > faxdetect_id ) ;
details - > faxdetect_id = - 1 ;
return f ;
}
/* only handle VOICE and CONTROL frames*/
switch ( f - > frametype ) {
case AST_FRAME_VOICE :
/* we have no DSP this means we not detecting CNG */
if ( ! faxdetect - > dsp ) {
2013-12-19 17:03:20 +00:00
return f ;
2011-10-05 06:50:18 +00:00
}
/* We can only process some formats*/
media formats: re-architect handling of media for performance improvements
In the old times media formats were represented using a bit field. This was
fast but had a few limitations.
1. Asterisk was limited in how many formats it could handle.
2. Formats, being a bit field, could not include any attribute information.
A format was strictly its type, e.g., "this is ulaw".
This was changed in Asterisk 10 (see
https://wiki.asterisk.org/wiki/display/AST/Media+Architecture+Proposal for
notes on that work) which led to the creation of the ast_format structure.
This structure allowed Asterisk to handle attributes and bundle information
with a format.
Additionally, ast_format_cap was created to act as a container for multiple
formats that, together, formed the capability of some entity. Another
mechanism was added to allow logic to be registered which performed format
attribute negotiation. Everywhere throughout the codebase Asterisk was
changed to use this strategy.
Unfortunately, in software, there is no free lunch. These new capabilities
came at a cost.
Performance analysis and profiling showed that we spend an inordinate
amount of time comparing, copying, and generally manipulating formats and
their related structures. Basic prototyping has shown that a reasonably
large performance improvement could be made in this area. This patch is the
result of that project, which overhauled the media format architecture
and its usage in Asterisk to improve performance.
Generally, the new philosophy for handling formats is as follows:
* The ast_format structure is reference counted. This removed a large amount
of the memory allocations and copying that was done in prior versions.
* In order to prevent race conditions while keeping things performant, the
ast_format structure is immutable by convention and lock-free. Violate this
tenet at your peril!
* Because formats are reference counted, codecs are also reference counted.
The Asterisk core generally provides built-in codecs and caches the
ast_format structures created to represent them. Generally, to prevent
inordinate amounts of module reference bumping, codecs and formats can be
added at run-time but cannot be removed.
* All compatibility with the bit field representation of codecs/formats has
been moved to a compatibility API. The primary user of this representation
is chan_iax2, which must continue to maintain its bit-field usage of formats
for interoperability concerns.
* When a format is negotiated with attributes, or when a format cannot be
represented by one of the cached formats, a new format object is created or
cloned from an existing format. That format may have the same codec
underlying it, but is a different format than a version of the format with
different attributes or without attributes.
* While formats are reference counted objects, the reference count maintained
on the format should be manipulated with care. Formats are generally cached
and will persist for the lifetime of Asterisk and do not explicitly need
to have their lifetime modified. An exception to this is when the user of a
format does not know where the format came from *and* the user may outlive
the provider of the format. This occurs, for example, when a format is read
from a channel: the channel may have a format with attributes (hence,
non-cached) and the user of the format may last longer than the channel (if
the reference to the channel is released prior to the format's reference).
For more information on this work, see the API design notes:
https://wiki.asterisk.org/wiki/display/AST/Media+Format+Rewrite
Finally, this work was the culmination of a large number of developer's
efforts. Extra thanks goes to Corey Farrell, who took on a large amount of the
work in the Asterisk core, chan_sip, and was an invaluable resource in peer
reviews throughout this project.
There were a substantial number of patches contributed during this work; the
following issues/patch names simply reflect some of the work (and will cause
the release scripts to give attribution to the individuals who work on them).
Reviews:
https://reviewboard.asterisk.org/r/3814
https://reviewboard.asterisk.org/r/3808
https://reviewboard.asterisk.org/r/3805
https://reviewboard.asterisk.org/r/3803
https://reviewboard.asterisk.org/r/3801
https://reviewboard.asterisk.org/r/3798
https://reviewboard.asterisk.org/r/3800
https://reviewboard.asterisk.org/r/3794
https://reviewboard.asterisk.org/r/3793
https://reviewboard.asterisk.org/r/3792
https://reviewboard.asterisk.org/r/3791
https://reviewboard.asterisk.org/r/3790
https://reviewboard.asterisk.org/r/3789
https://reviewboard.asterisk.org/r/3788
https://reviewboard.asterisk.org/r/3787
https://reviewboard.asterisk.org/r/3786
https://reviewboard.asterisk.org/r/3784
https://reviewboard.asterisk.org/r/3783
https://reviewboard.asterisk.org/r/3778
https://reviewboard.asterisk.org/r/3774
https://reviewboard.asterisk.org/r/3775
https://reviewboard.asterisk.org/r/3772
https://reviewboard.asterisk.org/r/3761
https://reviewboard.asterisk.org/r/3754
https://reviewboard.asterisk.org/r/3753
https://reviewboard.asterisk.org/r/3751
https://reviewboard.asterisk.org/r/3750
https://reviewboard.asterisk.org/r/3748
https://reviewboard.asterisk.org/r/3747
https://reviewboard.asterisk.org/r/3746
https://reviewboard.asterisk.org/r/3742
https://reviewboard.asterisk.org/r/3740
https://reviewboard.asterisk.org/r/3739
https://reviewboard.asterisk.org/r/3738
https://reviewboard.asterisk.org/r/3737
https://reviewboard.asterisk.org/r/3736
https://reviewboard.asterisk.org/r/3734
https://reviewboard.asterisk.org/r/3722
https://reviewboard.asterisk.org/r/3713
https://reviewboard.asterisk.org/r/3703
https://reviewboard.asterisk.org/r/3689
https://reviewboard.asterisk.org/r/3687
https://reviewboard.asterisk.org/r/3674
https://reviewboard.asterisk.org/r/3671
https://reviewboard.asterisk.org/r/3667
https://reviewboard.asterisk.org/r/3665
https://reviewboard.asterisk.org/r/3625
https://reviewboard.asterisk.org/r/3602
https://reviewboard.asterisk.org/r/3519
https://reviewboard.asterisk.org/r/3518
https://reviewboard.asterisk.org/r/3516
https://reviewboard.asterisk.org/r/3515
https://reviewboard.asterisk.org/r/3512
https://reviewboard.asterisk.org/r/3506
https://reviewboard.asterisk.org/r/3413
https://reviewboard.asterisk.org/r/3410
https://reviewboard.asterisk.org/r/3387
https://reviewboard.asterisk.org/r/3388
https://reviewboard.asterisk.org/r/3389
https://reviewboard.asterisk.org/r/3390
https://reviewboard.asterisk.org/r/3321
https://reviewboard.asterisk.org/r/3320
https://reviewboard.asterisk.org/r/3319
https://reviewboard.asterisk.org/r/3318
https://reviewboard.asterisk.org/r/3266
https://reviewboard.asterisk.org/r/3265
https://reviewboard.asterisk.org/r/3234
https://reviewboard.asterisk.org/r/3178
ASTERISK-23114 #close
Reported by: mjordan
media_formats_translation_core.diff uploaded by kharwell (License 6464)
rb3506.diff uploaded by mjordan (License 6283)
media_format_app_file.diff uploaded by kharwell (License 6464)
misc-2.diff uploaded by file (License 5000)
chan_mild-3.diff uploaded by file (License 5000)
chan_obscure.diff uploaded by file (License 5000)
jingle.diff uploaded by file (License 5000)
funcs.diff uploaded by file (License 5000)
formats.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
bridges.diff uploaded by file (License 5000)
mf-codecs-2.diff uploaded by file (License 5000)
mf-app_fax.diff uploaded by file (License 5000)
mf-apps-3.diff uploaded by file (License 5000)
media-formats-3.diff uploaded by file (License 5000)
ASTERISK-23715
rb3713.patch uploaded by coreyfarrell (License 5909)
rb3689.patch uploaded by mjordan (License 6283)
ASTERISK-23957
rb3722.patch uploaded by mjordan (License 6283)
mf-attributes-3.diff uploaded by file (License 5000)
ASTERISK-23958
Tested by: jrose
rb3822.patch uploaded by coreyfarrell (License 5909)
rb3800.patch uploaded by jrose (License 6182)
chan_sip.diff uploaded by mjordan (License 6283)
rb3747.patch uploaded by jrose (License 6182)
ASTERISK-23959 #close
Tested by: sgriepentrog, mjordan, coreyfarrell
sip_cleanup.diff uploaded by opticron (License 6273)
chan_sip_caps.diff uploaded by mjordan (License 6283)
rb3751.patch uploaded by coreyfarrell (License 5909)
chan_sip-3.diff uploaded by file (License 5000)
ASTERISK-23960 #close
Tested by: opticron
direct_media.diff uploaded by opticron (License 6273)
pjsip-direct-media.diff uploaded by file (License 5000)
format_cap_remove.diff uploaded by opticron (License 6273)
media_format_fixes.diff uploaded by opticron (License 6273)
chan_pjsip-2.diff uploaded by file (License 5000)
ASTERISK-23966 #close
Tested by: rmudgett
rb3803.patch uploaded by rmudgetti (License 5621)
chan_dahdi.diff uploaded by file (License 5000)
ASTERISK-24064 #close
Tested by: coreyfarrell, mjordan, opticron, file, rmudgett, sgriepentrog, jrose
rb3814.patch uploaded by rmudgett (License 5621)
moh_cleanup.diff uploaded by opticron (License 6273)
bridge_leak.diff uploaded by opticron (License 6273)
translate.diff uploaded by file (License 5000)
rb3795.patch uploaded by rmudgett (License 5621)
tls_fix.diff uploaded by mjordan (License 6283)
fax-mf-fix-2.diff uploaded by file (License 5000)
rtp_transfer_stuff uploaded by mjordan (License 6283)
rb3787.patch uploaded by rmudgett (License 5621)
media-formats-explicit-translate-format-3.diff uploaded by file (License 5000)
format_cache_case_fix.diff uploaded by opticron (License 6273)
rb3774.patch uploaded by rmudgett (License 5621)
rb3775.patch uploaded by rmudgett (License 5621)
rtp_engine_fix.diff uploaded by opticron (License 6273)
rtp_crash_fix.diff uploaded by opticron (License 6273)
rb3753.patch uploaded by mjordan (License 6283)
rb3750.patch uploaded by mjordan (License 6283)
rb3748.patch uploaded by rmudgett (License 5621)
media_format_fixes.diff uploaded by opticron (License 6273)
rb3740.patch uploaded by mjordan (License 6283)
rb3739.patch uploaded by mjordan (License 6283)
rb3734.patch uploaded by mjordan (License 6283)
rb3689.patch uploaded by mjordan (License 6283)
rb3674.patch uploaded by coreyfarrell (License 5909)
rb3671.patch uploaded by coreyfarrell (License 5909)
rb3667.patch uploaded by coreyfarrell (License 5909)
rb3665.patch uploaded by mjordan (License 6283)
rb3625.patch uploaded by coreyfarrell (License 5909)
rb3602.patch uploaded by coreyfarrell (License 5909)
format_compatibility-2.diff uploaded by file (License 5000)
core.diff uploaded by file (License 5000)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@419044 65c4cc65-6c06-0410-ace0-fbb531ad65f3
2014-07-20 22:06:33 +00:00
if ( ( ast_format_cmp ( f - > subclass . format , ast_format_slin ) ! = AST_FORMAT_CMP_EQUAL ) & &
( ast_format_cmp ( f - > subclass . format , ast_format_alaw ) ! = AST_FORMAT_CMP_EQUAL ) & &
( ast_format_cmp ( f - > subclass . format , ast_format_ulaw ) ! = AST_FORMAT_CMP_EQUAL ) ) {
return f ;
2011-10-05 06:50:18 +00:00
}
break ;
case AST_FRAME_CONTROL :
if ( ( f - > subclass . integer = = AST_CONTROL_T38_PARAMETERS ) & &
( faxdetect - > flags & FAX_DETECT_MODE_T38 ) ) {
break ;
}
return f ;
default :
return f ;
}
if ( f - > frametype = = AST_FRAME_VOICE ) {
f = ast_dsp_process ( chan , faxdetect - > dsp , f ) ;
if ( f - > frametype = = AST_FRAME_DTMF ) {
result = f - > subclass . integer ;
}
} else if ( ( f - > frametype = = AST_FRAME_CONTROL ) & & ( f - > datalen = = sizeof ( struct ast_control_t38_parameters ) ) ) {
control_params = f - > data . ptr ;
switch ( control_params - > request_response ) {
case AST_T38_NEGOTIATED :
case AST_T38_REQUEST_NEGOTIATE :
result = ' t ' ;
break ;
default :
break ;
}
}
if ( result ) {
2012-02-13 17:27:06 +00:00
const char * target_context = S_OR ( ast_channel_macrocontext ( chan ) , ast_channel_context ( chan ) ) ;
2011-10-05 06:50:18 +00:00
switch ( result ) {
case ' f ' :
case ' t ' :
ast_channel_unlock ( chan ) ;
if ( ast_exists_extension ( chan , target_context , " fax " , 1 ,
2012-02-29 16:52:47 +00:00
S_COR ( ast_channel_caller ( chan ) - > id . number . valid , ast_channel_caller ( chan ) - > id . number . str , NULL ) ) ) {
2011-10-05 06:50:18 +00:00
ast_channel_lock ( chan ) ;
2011-11-29 18:43:16 +00:00
ast_verb ( 2 , " Redirecting '%s' to fax extension due to %s detection \n " ,
2012-01-09 22:15:50 +00:00
ast_channel_name ( chan ) , ( result = = ' f ' ) ? " CNG " : " T38 " ) ;
2012-02-13 17:27:06 +00:00
pbx_builtin_setvar_helper ( chan , " FAXEXTEN " , ast_channel_exten ( chan ) ) ;
2011-10-05 06:50:18 +00:00
if ( ast_async_goto ( chan , target_context , " fax " , 1 ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_NOTICE , " Failed to async goto '%s' into fax of '%s' \n " , ast_channel_name ( chan ) , target_context ) ;
2011-10-05 06:50:18 +00:00
}
ast_frfree ( f ) ;
f = & ast_null_frame ;
} else {
ast_channel_lock ( chan ) ;
ast_log ( LOG_NOTICE , " FAX %s detected but no fax extension in context (%s) \n " ,
( result = = ' f ' ) ? " CNG " : " T38 " , target_context ) ;
}
}
ast_framehook_detach ( chan , details - > faxdetect_id ) ;
details - > faxdetect_id = - 1 ;
}
return f ;
}
/*! \brief Attach a faxdetect framehook object to a channel.
* \ param chan the channel to attach to
* \ param timeout remove framehook in this time if set
* \ return the faxdetect structure or NULL on error
* \ param flags required options
* \ retval - 1 error
*/
static int fax_detect_attach ( struct ast_channel * chan , int timeout , int flags )
{
struct fax_detect * faxdetect ;
struct ast_fax_session_details * details ;
struct ast_framehook_interface fr_hook = {
. version = AST_FRAMEHOOK_INTERFACE_VERSION ,
. event_cb = fax_detect_framehook ,
. destroy_cb = fax_detect_framehook_destroy ,
} ;
if ( ! ( details = find_or_create_details ( chan ) ) ) {
ast_log ( LOG_ERROR , " System cannot provide memory for session requirements. \n " ) ;
return - 1 ;
}
/* set up the frame hook*/
faxdetect = fax_detect_new ( chan , timeout , flags ) ;
if ( ! faxdetect ) {
ao2_ref ( details , - 1 ) ;
return - 1 ;
}
fr_hook . data = faxdetect ;
faxdetect - > details = details ;
ast_channel_lock ( chan ) ;
details - > faxdetect_id = ast_framehook_attach ( chan , & fr_hook ) ;
2014-07-18 16:28:10 +00:00
details - > faxdetect_timeout = timeout ;
details - > faxdetect_flags = flags ;
2011-10-05 06:50:18 +00:00
ast_channel_unlock ( chan ) ;
if ( details - > faxdetect_id < 0 ) {
ao2_ref ( faxdetect , - 1 ) ;
}
return details - > faxdetect_id ;
}
2010-03-02 23:11:06 +00:00
/*! \brief hash callback for ao2 */
static int session_hash_cb ( const void * obj , const int flags )
{
const struct ast_fax_session * s = obj ;
return s - > id ;
}
/*! \brief compare callback for ao2 */
static int session_cmp_cb ( void * obj , void * arg , int flags )
{
struct ast_fax_session * lhs = obj , * rhs = arg ;
return ( lhs - > id = = rhs - > id ) ? CMP_MATCH | CMP_STOP : 0 ;
}
2010-04-26 14:18:15 +00:00
/*! \brief fax session tab completion */
static char * fax_session_tab_complete ( struct ast_cli_args * a )
2010-03-02 23:11:06 +00:00
{
int tklen ;
int wordnum = 0 ;
char * name = NULL ;
struct ao2_iterator i ;
struct ast_fax_session * s ;
char tbuf [ 5 ] ;
if ( a - > pos ! = 3 ) {
return NULL ;
}
tklen = strlen ( a - > word ) ;
i = ao2_iterator_init ( faxregistry . container , 0 ) ;
while ( ( s = ao2_iterator_next ( & i ) ) ) {
2014-05-09 22:49:26 +00:00
snprintf ( tbuf , sizeof ( tbuf ) , " %u " , s - > id ) ;
2010-03-02 23:11:06 +00:00
if ( ! strncasecmp ( a - > word , tbuf , tklen ) & & + + wordnum > a - > n ) {
name = ast_strdup ( tbuf ) ;
ao2_ref ( s , - 1 ) ;
break ;
}
ao2_ref ( s , - 1 ) ;
}
2011-05-03 20:45:32 +00:00
ao2_iterator_destroy ( & i ) ;
2010-03-02 23:11:06 +00:00
return name ;
}
2010-04-26 14:18:15 +00:00
static char * cli_fax_show_version ( struct ast_cli_entry * e , int cmd , struct ast_cli_args * a )
{
struct fax_module * fax ;
switch ( cmd ) {
case CLI_INIT :
e - > command = " fax show version " ;
e - > usage =
" Usage: fax show version \n "
" Show versions of FAX For Asterisk components. \n " ;
return NULL ;
case CLI_GENERATE :
return NULL ;
}
if ( a - > argc ! = 3 ) {
return CLI_SHOWUSAGE ;
}
ast_cli ( a - > fd , " FAX For Asterisk Components: \n " ) ;
2010-06-22 16:17:14 +00:00
ast_cli ( a - > fd , " \t Applications: %s \n " , ast_get_version ( ) ) ;
2010-04-26 14:18:15 +00:00
AST_RWLIST_RDLOCK ( & faxmodules ) ;
AST_RWLIST_TRAVERSE ( & faxmodules , fax , list ) {
ast_cli ( a - > fd , " \t %s: %s \n " , fax - > tech - > description , fax - > tech - > version ) ;
}
AST_RWLIST_UNLOCK ( & faxmodules ) ;
ast_cli ( a - > fd , " \n " ) ;
return CLI_SUCCESS ;
}
2010-03-02 23:11:06 +00:00
/*! \brief enable FAX debugging */
static char * cli_fax_set_debug ( struct ast_cli_entry * e , int cmd , struct ast_cli_args * a )
{
int flag ;
const char * what ;
switch ( cmd ) {
case CLI_INIT :
e - > command = " fax set debug {on|off} " ;
2011-12-28 18:59:16 +00:00
e - > usage =
2010-03-02 23:11:06 +00:00
" Usage: fax set debug { on | off } \n "
" Enable/Disable FAX debugging on new FAX sessions. The basic FAX debugging will result in \n "
" additional events sent to manager sessions with 'call' class permissions. When \n "
" verbosity is greater than '5' events will be displayed to the console and audio versus \n "
" energy analysis will be performed and displayed to the console. \n " ;
return NULL ;
case CLI_GENERATE :
return NULL ;
}
what = a - > argv [ e - > args - 1 ] ; /* guaranteed to exist */
if ( ! strcasecmp ( what , " on " ) ) {
flag = 1 ;
} else if ( ! strcasecmp ( what , " off " ) ) {
flag = 0 ;
} else {
return CLI_SHOWUSAGE ;
}
global_fax_debug = flag ;
ast_cli ( a - > fd , " \n \n FAX Debug %s \n \n " , ( flag ) ? " Enabled " : " Disabled " ) ;
return CLI_SUCCESS ;
}
/*! \brief display registered FAX capabilities */
static char * cli_fax_show_capabilities ( struct ast_cli_entry * e , int cmd , struct ast_cli_args * a )
{
struct fax_module * fax ;
unsigned int num_modules = 0 ;
2011-12-28 18:59:16 +00:00
2010-03-02 23:11:06 +00:00
switch ( cmd ) {
case CLI_INIT :
e - > command = " fax show capabilities " ;
2011-12-28 18:59:16 +00:00
e - > usage =
2010-03-02 23:11:06 +00:00
" Usage: fax show capabilities \n "
" Shows the capabilities of the registered FAX technology modules \n " ;
return NULL ;
case CLI_GENERATE :
return NULL ;
}
ast_cli ( a - > fd , " \n \n Registered FAX Technology Modules: \n \n " ) ;
AST_RWLIST_RDLOCK ( & faxmodules ) ;
AST_RWLIST_TRAVERSE ( & faxmodules , fax , list ) {
ast_cli ( a - > fd , " %-15s : %s \n %-15s : %s \n %-15s : " , " Type " , fax - > tech - > type , " Description " , fax - > tech - > description , " Capabilities " ) ;
fax - > tech - > cli_show_capabilities ( a - > fd ) ;
num_modules + + ;
}
AST_RWLIST_UNLOCK ( & faxmodules ) ;
2014-05-09 22:49:26 +00:00
ast_cli ( a - > fd , " %u registered modules \n \n " , num_modules ) ;
2010-03-02 23:11:06 +00:00
return CLI_SUCCESS ;
}
2010-04-26 14:18:15 +00:00
/*! \brief display global defaults and settings */
static char * cli_fax_show_settings ( struct ast_cli_entry * e , int cmd , struct ast_cli_args * a )
{
struct fax_module * fax ;
char modems [ 128 ] = " " ;
2012-02-09 17:17:55 +00:00
struct fax_options options ;
2010-04-26 14:18:15 +00:00
switch ( cmd ) {
case CLI_INIT :
e - > command = " fax show settings " ;
e - > usage =
" Usage: fax show settings \n "
" Show the global settings and defaults of both the FAX core and technology modules \n " ;
return NULL ;
case CLI_GENERATE :
return NULL ;
}
2012-02-09 17:17:55 +00:00
get_general_options ( & options ) ;
2010-04-26 14:18:15 +00:00
ast_cli ( a - > fd , " FAX For Asterisk Settings: \n " ) ;
2012-02-09 17:17:55 +00:00
ast_cli ( a - > fd , " \t ECM: %s \n " , options . ecm ? " Enabled " : " Disabled " ) ;
ast_cli ( a - > fd , " \t Status Events: %s \n " , options . statusevents ? " On " : " Off " ) ;
2014-05-09 22:49:26 +00:00
ast_cli ( a - > fd , " \t Minimum Bit Rate: %u \n " , options . minrate ) ;
ast_cli ( a - > fd , " \t Maximum Bit Rate: %u \n " , options . maxrate ) ;
2012-02-09 17:17:55 +00:00
ast_fax_modem_to_str ( options . modems , modems , sizeof ( modems ) ) ;
2010-04-26 14:18:15 +00:00
ast_cli ( a - > fd , " \t Modem Modulations Allowed: %s \n " , modems ) ;
2015-01-09 14:53:09 +00:00
ast_cli ( a - > fd , " \t T.38 Negotiation Timeout: %u \n " , options . t38timeout ) ;
2010-04-26 14:18:15 +00:00
ast_cli ( a - > fd , " \n \n FAX Technology Modules: \n \n " ) ;
AST_RWLIST_RDLOCK ( & faxmodules ) ;
AST_RWLIST_TRAVERSE ( & faxmodules , fax , list ) {
ast_cli ( a - > fd , " %s (%s) Settings: \n " , fax - > tech - > type , fax - > tech - > description ) ;
fax - > tech - > cli_show_settings ( a - > fd ) ;
}
AST_RWLIST_UNLOCK ( & faxmodules ) ;
return CLI_SUCCESS ;
}
/*! \brief display details of a specified fax session */
2010-03-02 23:11:06 +00:00
static char * cli_fax_show_session ( struct ast_cli_entry * e , int cmd , struct ast_cli_args * a )
{
struct ast_fax_session * s , tmp ;
switch ( cmd ) {
case CLI_INIT :
e - > command = " fax show session " ;
e - > usage =
" Usage: fax show session <session number> \n "
" Shows status of the named FAX session \n " ;
return NULL ;
case CLI_GENERATE :
return fax_session_tab_complete ( a ) ;
}
if ( a - > argc ! = 4 ) {
return CLI_SHOWUSAGE ;
}
2014-05-09 22:49:26 +00:00
if ( sscanf ( a - > argv [ 3 ] , " %u " , & tmp . id ) ! = 1 ) {
2010-03-02 23:11:06 +00:00
ast_log ( LOG_ERROR , " invalid session id: '%s' \n " , a - > argv [ 3 ] ) ;
return RESULT_SUCCESS ;
}
ast_cli ( a - > fd , " \n FAX Session Details: \n -------------------- \n \n " ) ;
s = ao2_find ( faxregistry . container , & tmp , OBJ_POINTER ) ;
if ( s ) {
s - > tech - > cli_show_session ( s , a - > fd ) ;
ao2_ref ( s , - 1 ) ;
}
ast_cli ( a - > fd , " \n \n " ) ;
return CLI_SUCCESS ;
}
2011-12-28 18:59:16 +00:00
2014-07-18 15:49:46 +00:00
static int manager_fax_session ( struct mansession * s , const struct message * m )
{
const char * action_id = astman_get_header ( m , " ActionID " ) ;
const char * session_number = astman_get_header ( m , " SessionNumber " ) ;
char id_text [ 256 ] = " " ;
struct ast_fax_session * session ;
struct ast_fax_session find_session ;
if ( sscanf ( session_number , " %30u " , & find_session . id ) ! = 1 ) {
astman_send_error ( s , m , " Invalid session ID " ) ;
return 0 ;
}
session = ao2_find ( faxregistry . container , & find_session , OBJ_POINTER ) ;
if ( ! session ) {
astman_send_error ( s , m , " Session not found " ) ;
return 0 ;
}
if ( ! session - > tech - > manager_fax_session ) {
astman_send_error ( s , m , " Fax technology doesn't provide a handler for FAXSession " ) ;
ao2_ref ( session , - 1 ) ;
return 0 ;
}
if ( ! ast_strlen_zero ( action_id ) ) {
snprintf ( id_text , sizeof ( id_text ) , " ActionID: %s \r \n " , action_id ) ;
}
astman_send_ack ( s , m , " FAXSession event will follow " ) ;
session - > tech - > manager_fax_session ( s , id_text , session ) ;
ao2_ref ( session , - 1 ) ;
return 0 ;
}
2010-03-02 23:11:06 +00:00
/*! \brief display fax stats */
static char * cli_fax_show_stats ( struct ast_cli_entry * e , int cmd , struct ast_cli_args * a )
{
struct fax_module * fax ;
2011-12-28 18:59:16 +00:00
2010-03-02 23:11:06 +00:00
switch ( cmd ) {
case CLI_INIT :
e - > command = " fax show stats " ;
e - > usage =
" Usage: fax show stats \n "
" Shows a statistical summary of FAX transmissions \n " ;
return NULL ;
case CLI_GENERATE :
return NULL ;
}
ast_cli ( a - > fd , " \n FAX Statistics: \n --------------- \n \n " ) ;
ast_cli ( a - > fd , " %-20.20s : %d \n " , " Current Sessions " , faxregistry . active_sessions ) ;
2010-12-03 15:32:22 +00:00
ast_cli ( a - > fd , " %-20.20s : %d \n " , " Reserved Sessions " , faxregistry . reserved_sessions ) ;
2010-03-02 23:11:06 +00:00
ast_cli ( a - > fd , " %-20.20s : %d \n " , " Transmit Attempts " , faxregistry . fax_tx_attempts ) ;
ast_cli ( a - > fd , " %-20.20s : %d \n " , " Receive Attempts " , faxregistry . fax_rx_attempts ) ;
ast_cli ( a - > fd , " %-20.20s : %d \n " , " Completed FAXes " , faxregistry . fax_complete ) ;
ast_cli ( a - > fd , " %-20.20s : %d \n " , " Failed FAXes " , faxregistry . fax_failures ) ;
AST_RWLIST_RDLOCK ( & faxmodules ) ;
AST_RWLIST_TRAVERSE ( & faxmodules , fax , list ) {
fax - > tech - > cli_show_stats ( a - > fd ) ;
}
AST_RWLIST_UNLOCK ( & faxmodules ) ;
ast_cli ( a - > fd , " \n \n " ) ;
return CLI_SUCCESS ;
}
2014-07-18 15:49:46 +00:00
static int manager_fax_stats ( struct mansession * s , const struct message * m )
{
const char * action_id = astman_get_header ( m , " ActionID " ) ;
char id_text [ 256 ] = " " ;
astman_send_ack ( s , m , " FAXStats event will follow " ) ;
if ( ! ast_strlen_zero ( action_id ) ) {
snprintf ( id_text , sizeof ( id_text ) , " ActionID: %s \r \n " , action_id ) ;
}
astman_append ( s , " Event: FAXStats \r \n "
" %s "
" CurrentSessions: %d \r \n "
" ReservedSessions: %d \r \n "
" TransmitAttempts: %d \r \n "
" ReceiveAttempts: %d \r \n "
" CompletedFAXes: %d \r \n "
" FailedFAXes: %d \r \n "
" \r \n " ,
id_text ,
faxregistry . active_sessions , faxregistry . reserved_sessions ,
faxregistry . fax_tx_attempts , faxregistry . fax_rx_attempts ,
faxregistry . fax_complete , faxregistry . fax_failures ) ;
return 0 ;
}
static const char * fax_session_type ( struct ast_fax_session * s )
2011-12-28 18:59:16 +00:00
{
if ( s - > details - > caps & AST_FAX_TECH_AUDIO ) {
return " G.711 " ;
}
if ( s - > details - > caps & AST_FAX_TECH_T38 ) {
return " T.38 " ;
}
return " none " ;
}
2014-07-18 15:49:46 +00:00
const char * ast_fax_session_operation_str ( struct ast_fax_session * s )
2011-12-28 18:59:16 +00:00
{
if ( s - > details - > caps & AST_FAX_TECH_GATEWAY ) {
return " gateway " ;
}
if ( s - > details - > caps & AST_FAX_TECH_SEND ) {
return " send " ;
}
if ( s - > details - > caps & AST_FAX_TECH_RECEIVE ) {
return " receive " ;
}
if ( s - > details - > caps & AST_FAX_TECH_V21_DETECT ) {
return " V.21 " ;
}
return " none " ;
}
2010-03-02 23:11:06 +00:00
/*! \brief display fax sessions */
static char * cli_fax_show_sessions ( struct ast_cli_entry * e , int cmd , struct ast_cli_args * a )
{
struct ast_fax_session * s ;
struct ao2_iterator i ;
int session_count ;
2010-06-25 19:42:54 +00:00
char * filenames ;
2010-03-02 23:11:06 +00:00
switch ( cmd ) {
case CLI_INIT :
e - > command = " fax show sessions " ;
e - > usage =
" Usage: fax show sessions \n "
" Shows the current FAX sessions \n " ;
return NULL ;
case CLI_GENERATE :
return NULL ;
}
ast_cli ( a - > fd , " \n Current FAX Sessions: \n \n " ) ;
2010-04-26 14:18:15 +00:00
ast_cli ( a - > fd , " %-20.20s %-10.10s %-10.10s %-5.5s %-10.10s %-15.15s %-30.30s \n " ,
2010-06-25 19:42:54 +00:00
" Channel " , " Tech " , " FAXID " , " Type " , " Operation " , " State " , " File(s) " ) ;
2010-03-02 23:11:06 +00:00
i = ao2_iterator_init ( faxregistry . container , 0 ) ;
while ( ( s = ao2_iterator_next ( & i ) ) ) {
ao2_lock ( s ) ;
2010-06-25 19:42:54 +00:00
2011-06-30 18:22:28 +00:00
filenames = generate_filenames_string ( s - > details , " " , " , " ) ;
2010-06-25 19:42:54 +00:00
2014-05-09 22:49:26 +00:00
ast_cli ( a - > fd , " %-20.20s %-10.10s %-10u %-5.5s %-10.10s %-15.15s %-30s \n " ,
2010-04-26 14:18:15 +00:00
s - > channame , s - > tech - > type , s - > id ,
2014-07-18 15:49:46 +00:00
fax_session_type ( s ) ,
ast_fax_session_operation_str ( s ) ,
2011-06-30 18:22:28 +00:00
ast_fax_state_to_str ( s - > state ) , S_OR ( filenames , " " ) ) ;
2010-06-25 19:42:54 +00:00
ast_free ( filenames ) ;
2010-03-02 23:11:06 +00:00
ao2_unlock ( s ) ;
ao2_ref ( s , - 1 ) ;
}
2011-05-03 20:45:32 +00:00
ao2_iterator_destroy ( & i ) ;
2010-03-02 23:11:06 +00:00
session_count = ao2_container_count ( faxregistry . container ) ;
ast_cli ( a - > fd , " \n %d FAX sessions \n \n " , session_count ) ;
return CLI_SUCCESS ;
}
2014-07-18 15:49:46 +00:00
static int manager_fax_sessions_entry ( struct mansession * s ,
struct ast_fax_session * session , const char * id_text )
{
char * filenames ;
ao2_lock ( session ) ;
filenames = generate_filenames_string ( session - > details , " " , " , " ) ;
if ( ! filenames ) {
ast_log ( LOG_ERROR , " Error generating Files string " ) ;
ao2_unlock ( session ) ;
return - 1 ;
}
astman_append ( s , " Event: FAXSessionsEntry \r \n "
" %s " /* ActionID if present */
" Channel: %s \r \n " /* Channel name */
" Technology: %s \r \n " /* Fax session technology */
" SessionNumber: %u \r \n " /* Session ID */
" SessionType: %s \r \n " /* G711 or T38 */
" Operation: %s \r \n "
" State: %s \r \n "
" Files: %s \r \n "
" \r \n " ,
id_text , session - > channame , session - > tech - > type , session - > id ,
fax_session_type ( session ) , ast_fax_session_operation_str ( session ) ,
ast_fax_state_to_str ( session - > state ) , S_OR ( filenames , " " ) ) ;
ast_free ( filenames ) ;
ao2_unlock ( session ) ;
return 0 ;
}
static int manager_fax_sessions ( struct mansession * s , const struct message * m )
{
const char * action_id = astman_get_header ( m , " ActionID " ) ;
2015-01-09 18:16:54 +00:00
char id_text [ 256 ] ;
2014-07-18 15:49:46 +00:00
struct ast_fax_session * session ;
struct ao2_iterator iter ;
int session_count = 0 ;
2015-01-09 18:16:54 +00:00
id_text [ 0 ] = ' \0 ' ;
2014-07-18 15:49:46 +00:00
if ( ! ast_strlen_zero ( action_id ) ) {
snprintf ( id_text , sizeof ( id_text ) , " ActionID: %s \r \n " , action_id ) ;
}
2015-01-12 18:09:27 +00:00
astman_send_listack ( s , m , " FAXSessionsEntry event list will follow " , " Start " ) ;
2015-01-09 18:16:54 +00:00
2014-07-18 15:49:46 +00:00
iter = ao2_iterator_init ( faxregistry . container , 0 ) ;
while ( ( session = ao2_iterator_next ( & iter ) ) ) {
if ( ! manager_fax_sessions_entry ( s , session , id_text ) ) {
session_count + + ;
}
ao2_ref ( session , - 1 ) ;
}
ao2_iterator_destroy ( & iter ) ;
2015-01-09 18:16:54 +00:00
astman_send_list_complete_start ( s , m , " FAXSessionsComplete " , session_count ) ;
astman_append ( s , " Total: %d \r \n " , session_count ) ;
astman_send_list_complete_end ( s ) ;
2014-07-18 15:49:46 +00:00
return 0 ;
}
2010-03-02 23:11:06 +00:00
static struct ast_cli_entry fax_cli [ ] = {
2010-04-26 14:18:15 +00:00
AST_CLI_DEFINE ( cli_fax_show_version , " Show versions of FAX For Asterisk components " ) ,
2010-03-02 23:11:06 +00:00
AST_CLI_DEFINE ( cli_fax_set_debug , " Enable/Disable FAX debugging on new FAX sessions " ) ,
AST_CLI_DEFINE ( cli_fax_show_capabilities , " Show the capabilities of the registered FAX technology modules " ) ,
2010-04-26 14:18:15 +00:00
AST_CLI_DEFINE ( cli_fax_show_settings , " Show the global settings and defaults of both the FAX core and technology modules " ) ,
2010-03-02 23:11:06 +00:00
AST_CLI_DEFINE ( cli_fax_show_session , " Show the status of the named FAX sessions " ) ,
AST_CLI_DEFINE ( cli_fax_show_sessions , " Show the current FAX sessions " ) ,
AST_CLI_DEFINE ( cli_fax_show_stats , " Summarize FAX session history " ) ,
} ;
2012-02-09 17:17:55 +00:00
static void set_general_options ( const struct fax_options * options )
{
ast_rwlock_wrlock ( & options_lock ) ;
general_options = * options ;
ast_rwlock_unlock ( & options_lock ) ;
}
static void get_general_options ( struct fax_options * options )
{
ast_rwlock_rdlock ( & options_lock ) ;
* options = general_options ;
ast_rwlock_unlock ( & options_lock ) ;
}
2015-01-09 14:53:09 +00:00
static int set_t38timeout ( const char * value , unsigned int * t38timeout )
{
unsigned int timeout ;
if ( sscanf ( value , " %u " , & timeout ) ! = 1 ) {
ast_log ( LOG_ERROR , " Unable to get timeout from '%s' \n " , value ) ;
return - 1 ;
} else if ( timeout ) {
* t38timeout = timeout ;
} else {
ast_log ( LOG_ERROR , " T.38 negotiation timeout must be non-zero \n " ) ;
return - 1 ;
}
return 0 ;
}
2010-03-02 23:11:06 +00:00
/*! \brief configure res_fax */
2012-02-09 17:17:55 +00:00
static int set_config ( int reload )
2010-03-02 23:11:06 +00:00
{
struct ast_config * cfg ;
struct ast_variable * v ;
2012-02-09 17:17:55 +00:00
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 } ;
2010-08-09 14:52:21 +00:00
char modems [ 128 ] = " " ;
2012-02-09 17:17:55 +00:00
struct fax_options options ;
int res = 0 ;
options = default_options ;
2010-03-02 23:11:06 +00:00
2012-02-09 17:17:55 +00:00
/* When we're not reloading, we have to be certain to set the general options
* to the defaults in case config loading goes wrong at some point . On a reload ,
* the general options need to stay the same as what they were prior to the
* reload rather than being reset to the defaults .
*/
if ( ! reload ) {
set_general_options ( & options ) ;
}
2010-03-02 23:11:06 +00:00
/* read configuration */
2012-02-09 17:17:55 +00:00
if ( ! ( cfg = ast_config_load2 ( config , " res_fax " , config_flags ) ) ) {
ast_log ( LOG_NOTICE , " Configuration file '%s' not found, %s options. \n " ,
config , reload ? " not changing " : " using default " ) ;
2010-03-02 23:11:06 +00:00
return 0 ;
}
2011-07-28 15:30:30 +00:00
if ( cfg = = CONFIG_STATUS_FILEINVALID ) {
2012-02-09 17:17:55 +00:00
ast_log ( LOG_NOTICE , " Configuration file '%s' is invalid, %s options. \n " ,
config , reload ? " not changing " : " using default " ) ;
2011-07-28 15:30:30 +00:00
return 0 ;
}
2010-03-02 23:11:06 +00:00
if ( cfg = = CONFIG_STATUS_FILEUNCHANGED ) {
2012-02-09 17:17:55 +00:00
return 0 ;
}
if ( reload ) {
options = default_options ;
2010-03-02 23:11:06 +00:00
}
/* create configuration */
for ( v = ast_variable_browse ( cfg , " general " ) ; v ; v = v - > next ) {
int rate ;
if ( ! strcasecmp ( v - > name , " minrate " ) ) {
ast_debug ( 3 , " reading minrate '%s' from configuration file \n " , v - > value ) ;
2010-07-06 19:53:04 +00:00
if ( ( rate = fax_rate_str_to_int ( v - > value ) ) = = 0 ) {
2012-02-09 17:17:55 +00:00
res = - 1 ;
goto end ;
2010-03-02 23:11:06 +00:00
}
2012-02-09 17:17:55 +00:00
options . minrate = rate ;
2010-03-02 23:11:06 +00:00
} else if ( ! strcasecmp ( v - > name , " maxrate " ) ) {
ast_debug ( 3 , " reading maxrate '%s' from configuration file \n " , v - > value ) ;
2010-07-06 19:53:04 +00:00
if ( ( rate = fax_rate_str_to_int ( v - > value ) ) = = 0 ) {
2012-02-09 17:17:55 +00:00
res = - 1 ;
goto end ;
2010-03-02 23:11:06 +00:00
}
2012-02-09 17:17:55 +00:00
options . maxrate = rate ;
2010-03-02 23:11:06 +00:00
} else if ( ! strcasecmp ( v - > name , " statusevents " ) ) {
ast_debug ( 3 , " reading statusevents '%s' from configuration file \n " , v - > value ) ;
2012-02-09 17:17:55 +00:00
options . statusevents = ast_true ( v - > value ) ;
2010-04-26 14:18:15 +00:00
} else if ( ! strcasecmp ( v - > name , " ecm " ) ) {
ast_debug ( 3 , " reading ecm '%s' from configuration file \n " , v - > value ) ;
2012-02-09 17:17:55 +00:00
options . ecm = ast_true ( v - > value ) ;
2010-03-02 23:11:06 +00:00
} else if ( ( ! strcasecmp ( v - > name , " modem " ) ) | | ( ! strcasecmp ( v - > name , " modems " ) ) ) {
2012-02-09 17:17:55 +00:00
options . modems = 0 ;
update_modem_bits ( & options . modems , v - > value ) ;
2015-01-09 14:53:09 +00:00
} else if ( ! strcasecmp ( v - > name , " t38timeout " ) ) {
if ( set_t38timeout ( v - > value , & options . t38timeout ) ) {
res = - 1 ;
goto end ;
}
2010-03-02 23:11:06 +00:00
}
}
2012-02-09 17:17:55 +00:00
if ( options . maxrate < options . minrate ) {
2014-05-09 22:49:26 +00:00
ast_log ( LOG_ERROR , " maxrate %u is less than minrate %u \n " , options . maxrate , options . minrate ) ;
2012-02-09 17:17:55 +00:00
res = - 1 ;
goto end ;
2010-08-09 14:52:21 +00:00
}
2012-02-09 17:17:55 +00:00
if ( check_modem_rate ( options . modems , options . minrate ) ) {
ast_fax_modem_to_str ( options . modems , modems , sizeof ( modems ) ) ;
2014-05-09 22:49:26 +00:00
ast_log ( LOG_ERROR , " 'modems' setting '%s' is incompatible with 'minrate' setting %u \n " , modems , options . minrate ) ;
2012-02-09 17:17:55 +00:00
res = - 1 ;
goto end ;
2010-08-09 14:52:21 +00:00
}
2012-02-09 17:17:55 +00:00
if ( check_modem_rate ( options . modems , options . maxrate ) ) {
ast_fax_modem_to_str ( options . modems , modems , sizeof ( modems ) ) ;
2014-05-09 22:49:26 +00:00
ast_log ( LOG_ERROR , " 'modems' setting '%s' is incompatible with 'maxrate' setting %u \n " , modems , options . maxrate ) ;
2012-02-09 17:17:55 +00:00
res = - 1 ;
goto end ;
2010-08-09 14:52:21 +00:00
}
2012-02-09 17:17:55 +00:00
set_general_options ( & options ) ;
end :
ast_config_destroy ( cfg ) ;
return res ;
2010-03-02 23:11:06 +00:00
}
/*! \brief FAXOPT read function returns the contents of a FAX option */
static int acf_faxopt_read ( struct ast_channel * chan , const char * cmd , char * data , char * buf , size_t len )
{
struct ast_fax_session_details * details = find_details ( chan ) ;
int res = 0 ;
2010-06-25 19:42:54 +00:00
char * filenames ;
2010-03-02 23:11:06 +00:00
if ( ! details ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " channel '%s' can't read FAXOPT(%s) because it has never been written. \n " , ast_channel_name ( chan ) , data ) ;
2010-03-02 23:11:06 +00:00
return - 1 ;
}
if ( ! strcasecmp ( data , " ecm " ) ) {
ast_copy_string ( buf , details - > option . ecm ? " yes " : " no " , len ) ;
2011-06-30 18:22:28 +00:00
} else if ( ! strcasecmp ( data , " t38gateway " ) | | ! strcasecmp ( data , " gateway " ) | |
! strcasecmp ( data , " t38_gateway " ) | | ! strcasecmp ( data , " faxgateway " ) ) {
ast_copy_string ( buf , details - > gateway_id ! = - 1 ? " yes " : " no " , len ) ;
2011-10-05 06:50:18 +00:00
} else if ( ! strcasecmp ( data , " faxdetect " ) ) {
ast_copy_string ( buf , details - > faxdetect_id ! = - 1 ? " yes " : " no " , len ) ;
2010-03-02 23:11:06 +00:00
} else if ( ! strcasecmp ( data , " error " ) ) {
ast_copy_string ( buf , details - > error , len ) ;
} else if ( ! strcasecmp ( data , " filename " ) ) {
2010-04-26 14:18:15 +00:00
if ( AST_LIST_EMPTY ( & details - > documents ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " channel '%s' can't read FAXOPT(%s) because it has never been written. \n " , ast_channel_name ( chan ) , data ) ;
2010-04-26 14:18:15 +00:00
res = - 1 ;
} else {
ast_copy_string ( buf , AST_LIST_FIRST ( & details - > documents ) - > filename , len ) ;
}
2010-06-25 19:42:54 +00:00
} else if ( ! strcasecmp ( data , " filenames " ) ) {
if ( AST_LIST_EMPTY ( & details - > documents ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " channel '%s' can't read FAXOPT(%s) because it has never been written. \n " , ast_channel_name ( chan ) , data ) ;
2010-06-25 19:42:54 +00:00
res = - 1 ;
} else if ( ( filenames = generate_filenames_string ( details , " " , " , " ) ) ) {
ast_copy_string ( buf , filenames , len ) ;
ast_free ( filenames ) ;
} else {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " channel '%s' can't read FAXOPT(%s), there was an error generating the filenames list. \n " , ast_channel_name ( chan ) , data ) ;
2010-06-25 19:42:54 +00:00
res = - 1 ;
}
2010-03-02 23:11:06 +00:00
} else if ( ! strcasecmp ( data , " headerinfo " ) ) {
ast_copy_string ( buf , details - > headerinfo , len ) ;
} else if ( ! strcasecmp ( data , " localstationid " ) ) {
ast_copy_string ( buf , details - > localstationid , len ) ;
} else if ( ! strcasecmp ( data , " maxrate " ) ) {
2014-05-09 22:49:26 +00:00
snprintf ( buf , len , " %u " , details - > maxrate ) ;
2010-03-02 23:11:06 +00:00
} else if ( ! strcasecmp ( data , " minrate " ) ) {
2014-05-09 22:49:26 +00:00
snprintf ( buf , len , " %u " , details - > minrate ) ;
2010-03-02 23:11:06 +00:00
} else if ( ! strcasecmp ( data , " pages " ) ) {
2014-05-09 22:49:26 +00:00
snprintf ( buf , len , " %u " , details - > pages_transferred ) ;
2010-03-02 23:11:06 +00:00
} else if ( ! strcasecmp ( data , " rate " ) ) {
ast_copy_string ( buf , details - > transfer_rate , len ) ;
} else if ( ! strcasecmp ( data , " remotestationid " ) ) {
ast_copy_string ( buf , details - > remotestationid , len ) ;
} else if ( ! strcasecmp ( data , " resolution " ) ) {
ast_copy_string ( buf , details - > resolution , len ) ;
} else if ( ! strcasecmp ( data , " sessionid " ) ) {
2014-05-09 22:49:26 +00:00
snprintf ( buf , len , " %u " , details - > id ) ;
2010-03-02 23:11:06 +00:00
} else if ( ! strcasecmp ( data , " status " ) ) {
ast_copy_string ( buf , details - > result , len ) ;
} else if ( ! strcasecmp ( data , " statusstr " ) ) {
ast_copy_string ( buf , details - > resultstr , len ) ;
} else if ( ( ! strcasecmp ( data , " modem " ) ) | | ( ! strcasecmp ( data , " modems " ) ) ) {
ast_fax_modem_to_str ( details - > modems , buf , len ) ;
2015-01-09 14:53:09 +00:00
} else if ( ! strcasecmp ( data , " t38timeout " ) ) {
snprintf ( buf , len , " %u " , details - > t38timeout ) ;
2010-03-02 23:11:06 +00:00
} else {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " channel '%s' can't read FAXOPT(%s) because it is unhandled! \n " , ast_channel_name ( chan ) , data ) ;
2010-03-02 23:11:06 +00:00
res = - 1 ;
}
ao2_ref ( details , - 1 ) ;
return res ;
}
/*! \brief FAXOPT write function modifies the contents of a FAX option */
static int acf_faxopt_write ( struct ast_channel * chan , const char * cmd , char * data , const char * value )
{
int res = 0 ;
struct ast_fax_session_details * details ;
if ( ! ( details = find_or_create_details ( chan ) ) ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " channel '%s' can't set FAXOPT(%s) to '%s' because it failed to create a datastore. \n " , ast_channel_name ( chan ) , data , value ) ;
2010-03-02 23:11:06 +00:00
return - 1 ;
}
2012-01-09 22:15:50 +00:00
ast_debug ( 3 , " channel '%s' setting FAXOPT(%s) to '%s' \n " , ast_channel_name ( chan ) , data , value ) ;
2010-03-02 23:11:06 +00:00
if ( ! strcasecmp ( data , " ecm " ) ) {
2010-03-15 22:48:38 +00:00
const char * val = ast_skip_blanks ( value ) ;
if ( ast_true ( val ) ) {
details - > option . ecm = AST_FAX_OPTFLAG_TRUE ;
} else if ( ast_false ( val ) ) {
details - > option . ecm = AST_FAX_OPTFLAG_FALSE ;
} else {
ast_log ( LOG_WARNING , " Unsupported value '%s' passed to FAXOPT(ecm). \n " , value ) ;
}
2011-06-30 18:22:28 +00:00
} else if ( ! strcasecmp ( data , " t38gateway " ) | | ! strcasecmp ( data , " gateway " ) | |
! strcasecmp ( data , " t38_gateway " ) | | ! strcasecmp ( data , " faxgateway " ) ) {
const char * val = ast_skip_blanks ( value ) ;
2011-08-30 14:03:02 +00:00
char * timeout = strchr ( val , ' , ' ) ;
if ( timeout ) {
* timeout + + = ' \0 ' ;
}
2011-06-30 18:22:28 +00:00
if ( ast_true ( val ) ) {
if ( details - > gateway_id < 0 ) {
2011-08-31 16:31:30 +00:00
details - > gateway_timeout = 0 ;
if ( timeout ) {
unsigned int gwtimeout ;
if ( sscanf ( timeout , " %u " , & gwtimeout ) = = 1 ) {
details - > gateway_timeout = gwtimeout * 1000 ;
} else {
ast_log ( LOG_WARNING , " Unsupported timeout '%s' passed to FAXOPT(%s). \n " , timeout , data ) ;
}
}
2011-06-30 18:22:28 +00:00
details - > gateway_id = fax_gateway_attach ( chan , details ) ;
if ( details - > gateway_id < 0 ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " Error attaching T.38 gateway to channel %s. \n " , ast_channel_name ( chan ) ) ;
2011-06-30 18:22:28 +00:00
res = - 1 ;
} else {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " Attached T.38 gateway to channel %s. \n " , ast_channel_name ( chan ) ) ;
2011-06-30 18:22:28 +00:00
}
} else {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " Attempt to attach a T.38 gateway on channel (%s) with gateway already running. \n " , ast_channel_name ( chan ) ) ;
2011-06-30 18:22:28 +00:00
}
} else if ( ast_false ( val ) ) {
ast_framehook_detach ( chan , details - > gateway_id ) ;
details - > gateway_id = - 1 ;
} else {
ast_log ( LOG_WARNING , " Unsupported value '%s' passed to FAXOPT(%s). \n " , value , data ) ;
2011-10-05 06:50:18 +00:00
}
} else if ( ! strcasecmp ( data , " faxdetect " ) ) {
const char * val = ast_skip_blanks ( value ) ;
char * timeout = strchr ( val , ' , ' ) ;
unsigned int fdtimeout = 0 ;
int flags ;
int faxdetect ;
if ( timeout ) {
* timeout + + = ' \0 ' ;
}
if ( ast_true ( val ) | | ! strcasecmp ( val , " t38 " ) | | ! strcasecmp ( val , " cng " ) ) {
if ( details - > faxdetect_id < 0 ) {
if ( timeout & & ( sscanf ( timeout , " %u " , & fdtimeout ) = = 1 ) ) {
if ( fdtimeout > 0 ) {
fdtimeout = fdtimeout * 1000 ;
} else {
ast_log ( LOG_WARNING , " Timeout cannot be negative ignoring timeout \n " ) ;
}
}
if ( ! strcasecmp ( val , " t38 " ) ) {
flags = FAX_DETECT_MODE_T38 ;
} else if ( ! strcasecmp ( val , " cng " ) ) {
flags = FAX_DETECT_MODE_CNG ;
} else {
flags = FAX_DETECT_MODE_BOTH ;
}
faxdetect = fax_detect_attach ( chan , fdtimeout , flags ) ;
if ( faxdetect < 0 ) {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_ERROR , " Error attaching FAX detect to channel %s. \n " , ast_channel_name ( chan ) ) ;
2011-10-05 06:50:18 +00:00
res = - 1 ;
} else {
2012-01-09 22:15:50 +00:00
ast_debug ( 1 , " Attached FAX detect to channel %s. \n " , ast_channel_name ( chan ) ) ;
2011-10-05 06:50:18 +00:00
}
} else {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " Attempt to attach a FAX detect on channel (%s) with FAX detect already running. \n " , ast_channel_name ( chan ) ) ;
2011-10-05 06:50:18 +00:00
}
} else if ( ast_false ( val ) ) {
ast_framehook_detach ( chan , details - > faxdetect_id ) ;
details - > faxdetect_id = - 1 ;
} else {
ast_log ( LOG_WARNING , " Unsupported value '%s' passed to FAXOPT(%s). \n " , value , data ) ;
2011-06-30 18:22:28 +00:00
}
2010-03-02 23:11:06 +00:00
} else if ( ! strcasecmp ( data , " headerinfo " ) ) {
ast_string_field_set ( details , headerinfo , value ) ;
} else if ( ! strcasecmp ( data , " localstationid " ) ) {
ast_string_field_set ( details , localstationid , value ) ;
} else if ( ! strcasecmp ( data , " maxrate " ) ) {
details - > maxrate = fax_rate_str_to_int ( value ) ;
2010-07-06 19:53:04 +00:00
if ( ! details - > maxrate ) {
details - > maxrate = ast_fax_maxrate ( ) ;
}
2010-03-02 23:11:06 +00:00
} else if ( ! strcasecmp ( data , " minrate " ) ) {
details - > minrate = fax_rate_str_to_int ( value ) ;
2010-07-06 19:53:04 +00:00
if ( ! details - > minrate ) {
details - > minrate = ast_fax_minrate ( ) ;
}
2015-01-09 14:53:09 +00:00
} else if ( ! strcasecmp ( data , " t38timeout " ) ) {
if ( set_t38timeout ( value , & details - > t38timeout ) ) {
res = - 1 ;
}
2010-03-02 23:11:06 +00:00
} else if ( ( ! strcasecmp ( data , " modem " ) ) | | ( ! strcasecmp ( data , " modems " ) ) ) {
update_modem_bits ( & details - > modems , value ) ;
} else {
2012-01-09 22:15:50 +00:00
ast_log ( LOG_WARNING , " channel '%s' set FAXOPT(%s) to '%s' is unhandled! \n " , ast_channel_name ( chan ) , data , value ) ;
2010-03-02 23:11:06 +00:00
res = - 1 ;
}
ao2_ref ( details , - 1 ) ;
return res ;
}
/*! \brief FAXOPT dialplan function */
struct ast_custom_function acf_faxopt = {
. name = " FAXOPT " ,
. read = acf_faxopt_read ,
. write = acf_faxopt_write ,
} ;
/*! \brief unload res_fax */
static int unload_module ( void )
{
ast_cli_unregister_multiple ( fax_cli , ARRAY_LEN ( fax_cli ) ) ;
2011-12-28 18:59:16 +00:00
2010-03-02 23:11:06 +00:00
if ( ast_custom_function_unregister ( & acf_faxopt ) < 0 ) {
ast_log ( LOG_WARNING , " failed to unregister function '%s' \n " , acf_faxopt . name ) ;
}
if ( ast_unregister_application ( app_sendfax ) < 0 ) {
ast_log ( LOG_WARNING , " failed to unregister '%s' \n " , app_sendfax ) ;
}
if ( ast_unregister_application ( app_receivefax ) < 0 ) {
ast_log ( LOG_WARNING , " failed to unregister '%s' \n " , app_receivefax ) ;
}
2014-07-23 01:28:57 +00:00
ast_manager_unregister ( " FAXSessions " ) ;
ast_manager_unregister ( " FAXSession " ) ;
ast_manager_unregister ( " FAXStats " ) ;
2010-05-21 15:15:58 +00:00
if ( fax_logger_level ! = - 1 ) {
ast_logger_unregister_level ( " FAX " ) ;
}
2010-03-02 23:11:06 +00:00
ao2_ref ( faxregistry . container , - 1 ) ;
return 0 ;
}
2012-10-01 23:24:10 +00:00
/*!
* \ brief Load the module
*
* Module loading including tests for configuration or dependencies .
* This function can return AST_MODULE_LOAD_FAILURE , AST_MODULE_LOAD_DECLINE ,
* or AST_MODULE_LOAD_SUCCESS . If a dependency or environment variable fails
2013-06-22 13:58:07 +00:00
* tests return AST_MODULE_LOAD_FAILURE . If the module can not load the
* configuration file or other non - critical problem return
2012-10-01 23:24:10 +00:00
* AST_MODULE_LOAD_DECLINE . On success return AST_MODULE_LOAD_SUCCESS .
*/
2010-03-02 23:11:06 +00:00
static int load_module ( void )
{
int res ;
/* initialize the registry */
faxregistry . active_sessions = 0 ;
2010-12-03 15:32:22 +00:00
faxregistry . reserved_sessions = 0 ;
2010-03-02 23:11:06 +00:00
if ( ! ( faxregistry . container = ao2_container_alloc ( FAX_MAXBUCKETS , session_hash_cb , session_cmp_cb ) ) ) {
return AST_MODULE_LOAD_DECLINE ;
}
2011-12-28 18:59:16 +00:00
2012-02-09 17:17:55 +00:00
if ( set_config ( 0 ) < 0 ) {
2010-03-02 23:11:06 +00:00
ast_log ( LOG_ERROR , " failed to load configuration file '%s' \n " , config ) ;
ao2_ref ( faxregistry . container , - 1 ) ;
return AST_MODULE_LOAD_DECLINE ;
}
/* register CLI operations and applications */
2010-07-17 00:03:37 +00:00
if ( ast_register_application_xml ( app_sendfax , sendfax_exec ) < 0 ) {
2010-03-02 23:11:06 +00:00
ast_log ( LOG_WARNING , " failed to register '%s'. \n " , app_sendfax ) ;
ao2_ref ( faxregistry . container , - 1 ) ;
return AST_MODULE_LOAD_DECLINE ;
}
2010-07-17 00:03:37 +00:00
if ( ast_register_application_xml ( app_receivefax , receivefax_exec ) < 0 ) {
2010-03-02 23:11:06 +00:00
ast_log ( LOG_WARNING , " failed to register '%s'. \n " , app_receivefax ) ;
ast_unregister_application ( app_sendfax ) ;
ao2_ref ( faxregistry . container , - 1 ) ;
return AST_MODULE_LOAD_DECLINE ;
}
2011-06-30 18:22:28 +00:00
2014-07-18 15:49:46 +00:00
if ( ast_manager_register_xml ( " FAXSessions " , EVENT_FLAG_CALL , manager_fax_sessions ) ) {
ast_log ( LOG_WARNING , " failed to register 'FAXSessions' AMI command. \n " ) ;
ast_unregister_application ( app_receivefax ) ;
ast_unregister_application ( app_sendfax ) ;
ao2_ref ( faxregistry . container , - 1 ) ;
return AST_MODULE_LOAD_DECLINE ;
}
if ( ast_manager_register_xml ( " FAXSession " , EVENT_FLAG_CALL , manager_fax_session ) ) {
ast_log ( LOG_WARNING , " failed to register 'FAXSession' AMI command. \n " ) ;
ast_manager_unregister ( " FAXSession " ) ;
ast_unregister_application ( app_receivefax ) ;
ast_unregister_application ( app_sendfax ) ;
ao2_ref ( faxregistry . container , - 1 ) ;
return AST_MODULE_LOAD_DECLINE ;
}
if ( ast_manager_register_xml ( " FAXStats " , EVENT_FLAG_REPORTING , manager_fax_stats ) ) {
ast_log ( LOG_WARNING , " failed to register 'FAXStats' AMI command. \n " ) ;
ast_manager_unregister ( " FAXSession " ) ;
ast_manager_unregister ( " FAXSessions " ) ;
ast_unregister_application ( app_receivefax ) ;
ast_unregister_application ( app_sendfax ) ;
ao2_ref ( faxregistry . container , - 1 ) ;
return AST_MODULE_LOAD_DECLINE ;
}
2010-03-02 23:11:06 +00:00
ast_cli_register_multiple ( fax_cli , ARRAY_LEN ( fax_cli ) ) ;
2011-10-03 09:49:38 +00:00
res = ast_custom_function_register ( & acf_faxopt ) ;
2010-05-21 15:15:58 +00:00
fax_logger_level = ast_logger_register_level ( " FAX " ) ;
2010-03-02 23:11:06 +00:00
return res ;
}
2012-02-09 17:17:55 +00:00
static int reload_module ( void )
{
set_config ( 1 ) ;
return 0 ;
}
2010-03-02 23:11:06 +00:00
2010-07-20 19:35:02 +00:00
AST_MODULE_INFO ( ASTERISK_GPL_KEY , AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , " Generic FAX Applications " ,
2015-05-06 00:49:04 +00:00
. support_level = AST_MODULE_SUPPORT_CORE ,
. load = load_module ,
. unload = unload_module ,
. reload = reload_module ,
. load_pri = AST_MODPRI_APP_DEPEND ,
) ;