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
  
						 
					
						
							
								
									
										
										
										
											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" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# 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 > 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-13 13:46:17 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													< enum  name = " negotiate_both " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														< para > R / W  Upon  v21  detection  allow  gateway  to  send  negotiation  requests  to  both  T .38  endpoints ,  and  do  not  wait  on  the  " other "  side  to  initiate  ( yes | no ) < / 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 " > 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-20 12:14:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													< para > Filename  of  the  image  being  sent / received  for  this  FAX  session .  This  field  is  not 
							 
						 
					
						
							
								
									
										
										
										
											2014-07-18 15:49:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													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 " > 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-20 12:14:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													< para > Total  number  of  bad  lines  sent / received  during  this  session .  This  field  is  not 
							 
						 
					
						
							
								
									
										
										
										
											2014-07-18 15:49:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													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 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 13:05:10 -05: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 ) ;  
						 
					
						
							
								
									
										
										
										
											2016-05-02 17:52:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_fax_session  * fax_v21_session_new  ( struct  ast_channel  * chan ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-07-18 16:28:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										new_details - > is_t38_negotiated  =  old_details - > is_t38_negotiated ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-07-18 16:28:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-13 13:46:17 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									d - > negotiate_both  =  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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2019-03-06 16:04:57 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * m [ 5 ] ,  * tok ,  * v  =  ( char  * )  value ,  * rest ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-02 23:11:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									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  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-06 16:04:57 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tok  =  strtok_r ( v ,  " ,  " ,  & rest ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-03-06 16:04:57 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											tok  =  strtok_r ( NULL ,  " ,  " ,  & rest ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-02 23:11:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 13:05:10 -05: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 13:05:10 -05: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 13:05:10 -05: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 13:05:10 -05: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_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_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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-28 16:35:17 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										s - > details  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-02 23:11:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 19:24:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ast_module_running_ref ( faxmod - > tech - > module ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-03 15:32:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 4 ,  " Reserving a FAX session from '%s'. \n " ,  faxmod - > tech - > description ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-29 19:24:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! ast_module_running_ref ( faxmod - > tech - > module ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-03 15:32:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 4 ,  " Requesting a new FAX session from '%s'. \n " ,  faxmod - > tech - > description ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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} " , 
							 
						 
					
						
							
								
									
										
										
										
											2016-10-12 16:24:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" type " ,  " status " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" operation " ,  ( details - > caps  &  AST_FAX_TECH_GATEWAY ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											?  " gateway " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											:  ( details - > caps  &  AST_FAX_TECH_RECEIVE )  ?  " receive "  :  " send " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" status " ,  status , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" local_station_id " ,  AST_JSON_UTF8_VALIDATE ( details - > localstationid ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" filenames " ,  json_filenames ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 20:44:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									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 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-20 21:01:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									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 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 11:14:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " REMOTESTATIONID " ,  AST_JSON_UTF8_VALIDATE ( details - > remotestationid ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " LOCALSTATIONID " ,  AST_JSON_UTF8_VALIDATE ( details - > localstationid ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( details - > is_t38_negotiated )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-02 17:08:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  " FAXMODE " ,  " T38 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  " FAXMODE " ,  " audio " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-09-29 20:08:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Make sure one or the other is set to avoid race condition */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( t38negotiated )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										details - > caps  | =  AST_FAX_TECH_T38 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										details - > caps  | =  AST_FAX_TECH_AUDIO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									details - > is_t38_negotiated  =  t38negotiated ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( details - > caps  &  AST_FAX_TECH_T38 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														details - > is_t38_negotiated  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														t38_parameters . request_response  =  AST_T38_NEGOTIATED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														t38_parameters . request_response  =  AST_T38_REFUSED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-02 23:11:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													details - > is_t38_negotiated  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-02 23:11:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 11:14:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										remote_station_id  =  AST_JSON_UTF8_VALIDATE ( 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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 11:14:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										local_station_id  =  AST_JSON_UTF8_VALIDATE ( 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 14:04:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										json_object  =  ast_json_pack ( " {s: s, s: s, s: s, s: s, s: s, s: s, s: o} " , 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-22 13:58:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												" 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 ,  " " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2015-12-14 14:04:15 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												" filenames " ,  ast_json_ref ( json_array ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 20:44:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-02 17:08:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " FAXMODE " ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-20 21:01:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 11:14:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										remote_station_id  =  AST_JSON_UTF8_VALIDATE ( 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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 11:14:10 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										local_station_id  =  AST_JSON_UTF8_VALIDATE ( 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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-02 17:08:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " FAXMODE " ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-20 21:01:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-05-02 17:52:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_fax_session  * fax_v21_session_new  ( struct  ast_channel  * chan )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_fax_session_details  * v21_details ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_fax_session  * v21_session ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! chan  | |  ! ( v21_details  =  session_details_new ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									v21_details - > caps  =  AST_FAX_TECH_V21_DETECT ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-06-22 16:04:54 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									v21_session  =  fax_session_new ( v21_details ,  chan ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_ref ( v21_details ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-02 17:52:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  v21_session ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! gateway )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-05-02 17:52:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( gateway - > chan_v21_session  =  fax_v21_session_new ( chan ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Can't create V21 session on chan %s for T.38 gateway session \n " ,  ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ao2_ref ( gateway ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:16:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Create  a  fax  session  and  start  T .30 < - > T .38  gateway  mode 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  gateway  a  fax  gateway  object 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  details  fax  session  details 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  chan  active  channel 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:16:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ pre  chan  is  locked  on  entry 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  0  on  error  1  on  success 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-08-29 07:18:08 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* if the fax gateway is already started then do nothing */ 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-28 16:35:17 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( gateway - > s  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										gateway - > s - > state  ! =  AST_FAX_STATE_RESERVED  & &  gateway - > s - > state  ! =  AST_FAX_STATE_INACTIVE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-08-29 07:18:08 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 18:54:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* if we start gateway we don't need v21 detection sessions any more */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									destroy_v21_sessions ( gateway ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:16:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \pre chan is locked on entry */  
						 
					
						
							
								
									
										
										
										
											2019-05-29 18:54:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_frame  * fax_gateway_request_t38 ( struct  fax_gateway  * gateway ,  struct  ast_channel  * chan )  
						 
					
						
							
								
									
										
										
										
											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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 18:54:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-11 13:29:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 18:54:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-11 13:29:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gateway - > t38_state  =  T38_STATE_NEGOTIATING ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gateway - > timeout_start  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:16:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \pre chan is locked on entry */  
						 
					
						
							
								
									
										
										
										
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:02:35 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										enum  ast_t38_state  state_other ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 18:54:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										enum  ast_t38_state  state_active ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_frame  * fp ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-13 13:46:17 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  ast_fax_session_details  * details ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  negotiate_both  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  The  default  behavior  is  to  wait  for  the  active  endpoint  to  initiate  negotiation . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  Find  out  if  this  has  been  overridden .  If  so ,  instead  of  waiting  have  Asterisk 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  initiate  the  negotiation  requests  out  to  both  endpoints . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										details  =  find_or_create_details ( active ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( details )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											negotiate_both  =  details - > negotiate_both ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ao2_ref ( details ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Detect v21 - no session details for channel '%s' \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:02:35 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-28 18:59:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										destroy_v21_sessions ( gateway ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:02:35 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 18:54:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										state_active  =  ast_channel_get_t38_state ( active ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:02:35 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										state_other  =  ast_channel_get_t38_state ( other ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 18:54:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " detected v21 preamble from %s \n " ,  ast_channel_name ( active ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( state_active  = =  T38_STATE_UNKNOWN  | |  state_other  = =  T38_STATE_UNKNOWN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ( fp  =  fax_gateway_request_t38 ( gateway ,  chan ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* May be called endpoint is improperly configured to rely on the calling endpoint
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  to  initiate  T .38  re - INVITEs ,  send  T .38  negotiation  request  to  called  endpoint  */ 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-13 13:46:17 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( negotiate_both  & &  state_active  = =  T38_STATE_UNKNOWN )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 18:54:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " sending T.38 negotiation request to %s \n " ,  ast_channel_name ( active ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( active  = =  chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_write ( active ,  fp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( active  = =  chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( state_other  = =  T38_STATE_UNKNOWN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " sending T.38 negotiation request to %s \n " ,  ast_channel_name ( other ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  fp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 18:54:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " neither %s nor %s 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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 12:31:24 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \pre chan is locked on entry */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  fax_gateway_indicate_t38 ( struct  ast_channel  * chan ,  struct  ast_channel  * active ,  struct  ast_control_t38_parameters  * control_params )  
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( active  = =  chan )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 12:31:24 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_indicate_data ( chan ,  AST_CONTROL_T38_PARAMETERS ,  control_params ,  sizeof ( * control_params ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-22 12:31:24 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_queue_control_data ( chan ,  AST_CONTROL_T38_PARAMETERS ,  control_params ,  sizeof ( * control_params ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:16:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  T38  Gateway  Negotiate  t38  parameters 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ 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 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:16:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ pre  chan  is  locked  on  entry 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ 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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:02:35 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									enum  ast_t38_state  state_other ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:02:35 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										state_other  =  ast_channel_get_t38_state ( other ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-11 13:29:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:02:35 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( state_other  = =  T38_STATE_UNKNOWN )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* 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 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:02:35 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( state_other  = =  T38_STATE_UNAVAILABLE  | |  state_other  = =  T38_STATE_REJECTED )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* 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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												details - > is_t38_negotiated  =  chan  = =  active ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												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 ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											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 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											details - > is_t38_negotiated  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											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 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											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 .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:02:35 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										state_other  =  ast_channel_get_t38_state ( other ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( state_other  = =  T38_STATE_UNKNOWN )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											gateway - > t38_state  =  T38_STATE_UNAVAILABLE ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-29 18:54:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( state_other  ! =  T38_STATE_NEGOTIATING )  { 
							 
						 
					
						
							
								
									
										
										
										
											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 ,  " 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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											control_params - > request_response  =  AST_T38_REQUEST_TERMINATE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fax_gateway_indicate_t38 ( chan ,  active ,  control_params ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											gateway - > t38_state  =  T38_STATE_NEGOTIATED ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											details - > is_t38_negotiated  =  chan  = =  active ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											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 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " error 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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											gateway - > t38_state  =  T38_STATE_REJECTED ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											details - > is_t38_negotiated  =  chan  = =  other ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										details - > is_t38_negotiated  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:16:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  T .30 < - > T .38  gateway  framehook . 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  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  * ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:16:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ pre  chan  is  locked  on  entry 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ 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 18:05:37 -05: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 18:05:37 -05: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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:02:35 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										enum  ast_t38_state  state_chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										enum  ast_t38_state  state_peer ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-06-03 10:23:31 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  chan_is_hungup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  peer_is_hungup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										chan_is_hungup  =  ast_check_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peer_is_hungup  =  ast_check_hangup ( peer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Don't start a gateway if either channel is hung up */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( chan_is_hungup  | |  peer_is_hungup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:02:35 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										state_chan  =  ast_channel_get_t38_state ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										state_peer  =  ast_channel_get_t38_state ( peer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* don't start a gateway if neither channel can handle T.38 */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:02:35 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( state_chan  = =  T38_STATE_UNAVAILABLE  & &  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 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-22 16:31:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											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 18:05:37 -05: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 18:05:37 -05: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 18:05:37 -05: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 18:05:37 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_unlock ( peer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										gateway - > bridged  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-02 17:52:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ( gateway - > peer_v21_session  =  fax_v21_session_new ( peer ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " Can't create V21 session on chan %s for T.38 gateway session \n " ,  ast_channel_name ( peer ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_framehook_detach ( chan ,  gateway - > framehook ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									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 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-22 16:31:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-28 16:35:17 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! gateway - > s  | |  ! gateway - > s - > tech_pvt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " no FAX session on chan %s for T.38 gateway session, odd " ,  ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2020-05-27 05:47:07 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ( f  =  ast_translate ( readtrans ,  f ,  event  = =  AST_FRAMEHOOK_EVENT_WRITE  ?  0  :  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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 11:16:04 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( global_fax_debug )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										details - > option . debug  =  AST_FAX_OPTFLAG_TRUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-05-02 17:52:16 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											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 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:39:01 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										details - > is_t38_negotiated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 17:24:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ao2_cleanup ( faxdetect - > details ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												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 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 17:24:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  timeout  in  ms  to  remove  framehook  in  this  time  if  not  zero 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-05 06:50:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ 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 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 17:24:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ast_tvzero ( faxdetect - > timeout_start ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										& &  ast_tvdiff_ms ( ast_tvnow ( ) ,  faxdetect - > timeout_start )  >  details - > faxdetect_timeout )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " FAXOPT(faxdetect) timeout on %s \n " ,  ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-05 06:50:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 17:33:29 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  char  * target_context ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-05 06:50:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										switch  ( result )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ' f ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ' t ' : 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 17:33:29 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											target_context  =  S_OR ( ast_channel_macrocontext ( chan ) ,  ast_channel_context ( chan ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-10-05 06:50:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 17:33:29 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-05 06:50:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											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-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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_NOTICE ,  " FAX %s detected but no fax extension in context (%s) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													( result  = =  ' f ' )  ?  " CNG "  :  " T38 " ,  target_context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 17:33:29 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_framehook_detach ( chan ,  details - > faxdetect_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											details - > faxdetect_id  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-05 06:50:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Attach a faxdetect framehook object to a channel.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  chan  the  channel  to  attach  to 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 17:24:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  timeout  in  ms  to  remove  framehook  in  this  time  if  not  zero 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-05 06:50:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ 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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-28 18:15:40 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " %-22s : %s \n " ,  " channel " ,  s - > channame ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-02 23:11:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										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 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-05-28 18:15:40 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  " %-30.30s %-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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-05-28 18:15:40 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " %-30.30s %-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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-13 13:46:17 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( ! strcasecmp ( data ,  " negotiate_both " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( buf ,  details - > negotiate_both  ! =  - 1  ?  " yes "  :  " no " ,  len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 17:24:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( sscanf ( timeout ,  " %30u " ,  & gwtimeout )  = =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-18 21:02:17 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														details - > gateway_timeout  =  gwtimeout  *  1000 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 16:31:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													}  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 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:42:08 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_framehook_detach ( chan ,  details - > gateway_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:42:08 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-30 18:22:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											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 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 17:24:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( timeout )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( sscanf ( timeout ,  " %30u " ,  & fdtimeout )  = =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2017-11-18 21:02:17 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														fdtimeout  * =  1000 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-05 06:50:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-12 17:24:54 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING ,  " Unsupported timeout '%s' passed to FAXOPT(%s). \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															timeout ,  data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-05 06:50:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												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 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:42:08 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-05 06:50:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_framehook_detach ( chan ,  details - > faxdetect_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-23 10:42:08 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-05 06:50:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											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 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-13 13:46:17 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( ! strcasecmp ( data ,  " negotiate_both " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										details - > negotiate_both  =  ast_true ( ast_skip_blanks ( value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-02 23:11:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  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 */  
						 
					
						
							
								
									
										
										
										
											2021-08-25 16:29:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_custom_function  acf_faxopt  =  {  
						 
					
						
							
								
									
										
										
										
											2010-03-02 23:11:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									. 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 ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-19 15:10:02 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									faxregistry . container  =  ao2_container_alloc_hash ( AO2_ALLOC_OPT_LOCK_MUTEX ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										FAX_MAXBUCKETS ,  session_hash_cb ,  NULL ,  session_cmp_cb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! faxregistry . container )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-02 23:11:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										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-05 20:49:04 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. support_level  =  AST_MODULE_SUPPORT_CORE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. load  =  load_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. unload  =  unload_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. reload  =  reload_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. load_pri  =  AST_MODPRI_APP_DEPEND , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ;