2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Asterisk  - -  An  open  source  telephony  toolkit . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( C )  1999  -  2008 ,  Digium ,  Inc . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Mark  Spencer  < markster @ digium . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  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 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Supports  RTP  and  RTCP  with  Symmetric  RTP  support  for  NAT  traversal . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ author  Mark  Spencer  < markster @ digium . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note  RTP  is  defined  in  RFC  3550. 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-30 04:08:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ ingroup  rtp_engines 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ASTERISK_FILE_VERSION ( __FILE__ ,  " $Revision$ " )  
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <sys/time.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <signal.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <fcntl.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <math.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/stun.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/pbx.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/frame.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/channel.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/acl.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/config.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/lock.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/utils.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/netsock.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/cli.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/manager.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/unaligned.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/module.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/rtp_engine.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define MAX_TIMESTAMP_SKEW	640 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RTP_SEQ_MOD     (1<<16)	 /*!< A sequence number can't be more than 16 bits */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RTCP_DEFAULT_INTERVALMS   5000	 /*!< Default milli-seconds between RTCP reports we send */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RTCP_MIN_INTERVALMS       500	 /*!< Min milli-seconds between RTCP reports we send */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RTCP_MAX_INTERVALMS       60000	 /*!< Max milli-seconds between RTCP reports we send */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define DEFAULT_RTP_START 5000  /*!< Default port number to start allocating RTP ports from */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define DEFAULT_RTP_END 31000   /*!< Default maximum port number to end allocating RTP ports at */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define MINIMUM_RTP_PORT 1024  /*!< Minimum port number to accept */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define MAXIMUM_RTP_PORT 65535  /*!< Maximum port number to accept */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RTCP_PT_FUR     192 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RTCP_PT_SR      200 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RTCP_PT_RR      201 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RTCP_PT_SDES    202 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RTCP_PT_BYE     203 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RTCP_PT_APP     204 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define RTP_MTU		1200 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-13 13:39:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define DEFAULT_DTMF_TIMEOUT (150 * (8000  /  1000))	 /*!< samples */ 
  
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define ZFONE_PROFILE_ID 0x505a 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  dtmftimeout  =  DEFAULT_DTMF_TIMEOUT ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtpstart  =  DEFAULT_RTP_START ; 			/*!< First port for RTP sessions (set in rtp.conf) */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtpend  =  DEFAULT_RTP_END ; 			/*!< Last port for RTP sessions (set in rtp.conf) */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtpdebug ; 			/*!< Are we debugging? */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtcpdebug ; 			/*!< Are we debugging RTCP? */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtcpstats ; 			/*!< Are we debugging RTCP? */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtcpinterval  =  RTCP_DEFAULT_INTERVALMS ;  /*!< Time between rtcp reports in millisecs */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  sockaddr_in  rtpdebugaddr ; 	/*!< Debug packets to/from this host */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  sockaddr_in  rtcpdebugaddr ; 	/*!< Debug RTCP packets to/from this host */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef SO_NO_CHECK 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  nochecksums ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  strictrtp ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								enum  strict_rtp_state  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									STRICT_RTP_OPEN  =  0 ,  /*! No RTP packets should be dropped, all sources accepted */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									STRICT_RTP_LEARN ,     /*! Accept next packet as source */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									STRICT_RTP_CLOSED ,    /*! Drop all RTP packets not coming from source that was learned */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define FLAG_3389_WARNING               (1 << 0) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define FLAG_NAT_ACTIVE                 (3 << 1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define FLAG_NAT_INACTIVE               (0 << 1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define FLAG_NAT_INACTIVE_NOWARN        (1 << 1) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define FLAG_NEED_MARKER_BIT            (1 << 3) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define FLAG_DTMF_COMPENSATE            (1 << 4) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief RTP session description */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  ast_rtp  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  rawdata [ 8192  +  AST_FRIENDLY_OFFSET ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  ssrc ; 		/*!< Synchronization source, RFC 3550, page 10. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  themssrc ; 		/*!< Their SSRC */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  rxssrc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  lastts ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  lastrxts ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  lastividtimestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  lastovidtimestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  lastitexttimestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  lastotexttimestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  lasteventseqn ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  lastrxseqno ;                 /*!< Last received sequence number */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  short  seedrxseqno ;      /*!< What sequence number did they start with?*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  seedrxts ;           /*!< What RTP timestamp did they start with? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  rxcount ;            /*!< How many packets have we received? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  rxoctetcount ;       /*!< How many octets have we received? should be rxcount *160*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  txcount ;            /*!< How many packets have we sent? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  txoctetcount ;       /*!< How many octets have we sent? (txcount*160)*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  cycles ;             /*!< Shifted count of sequence number cycles */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  rxjitter ;                 /*!< Interarrival jitter at the moment */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  rxtransit ;                /*!< Relative transit time for previous packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  lasttxformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  lastrxformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  rtptimeout ; 			/*!< RTP timeout time (negative or zero means disabled, negative value means temporarily disabled) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  rtpholdtimeout ; 		/*!< RTP timeout when on hold (negative or zero means disabled, negative value means temporarily disabled). */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  rtpkeepalive ; 		/*!< Send RTP comfort noice packets for keepalive */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* DTMF Reception Variables */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  resp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  lastevent ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-13 13:39:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  int  dtmf_duration ;      /*!< Total duration in samples since the digit start event */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  dtmf_timeout ;       /*!< When this timestamp is reached we consider END frame lost and forcibly abort digit */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									unsigned  int  dtmfsamples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* DTMF Transmission Variables */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  lastdigitts ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  sending_digit ; 	/*!< boolean - are we sending digits */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  send_digit ; 	/*!< digit we are sending */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  send_payload ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  send_duration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  timeval  rxcore ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  timeval  txcore ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  drxcore ;                  /*!< The double representation of the first received packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  timeval  lastrx ;           /*!< timeval when we last received a packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  timeval  dtmfmute ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_smoother  * smoother ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  * ioid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  short  seqno ; 		/*!< Sequence number, RFC 3550, page 13. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  short  rxseqno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sched_context  * sched ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  io_context  * io ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									void  * data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtcp  * rtcp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * bridged ;         /*!< Who we are Packet bridged to */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									enum  strict_rtp_state  strict_rtp_state ;  /*!< Current state that strict RTP protection is in */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sockaddr_in  strict_rtp_address ;   /*!< Remote address information for strict RTP purposes */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-18 15:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sockaddr_in  alt_rtp_address ;  /*!<Alternate remote address information */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  rtp_red  * red ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Structure  defining  an  RTCP  session . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  The  concept  " RTCP session "  is  not  defined  in  RFC  3550 ,  but  since 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  this  structure  is  analogous  to  ast_rtp ,  which  tracks  a  RTP  session , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  it  is  logical  to  think  of  this  as  a  RTCP  session . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  RTCP  packet  is  defined  on  page  9  of  RFC  3550. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  ast_rtcp  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  rtcp_info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  s ; 				/*!< Socket */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sockaddr_in  us ; 		/*!< Socket representation of the local endpoint. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sockaddr_in  them ; 	/*!< Socket representation of the remote endpoint. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  soc ; 		/*!< What they told us */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  spc ; 		/*!< What they told us */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  themrxlsr ; 		/*!< The middle 32 bits of the NTP timestamp in the last received SR*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  timeval  rxlsr ; 		/*!< Time when we got their last SR */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  timeval  txlsr ; 		/*!< Time when we sent or last SR*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  expected_prior ; 	/*!< no. packets in previous interval */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  received_prior ; 	/*!< no. packets received in previous interval */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  schedid ; 			/*!< Schedid returned from ast_sched_add() to schedule RTCP-transmissions*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  rr_count ; 		/*!< number of RRs we've sent, not including report blocks in SR's */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  sr_count ; 		/*!< number of SRs we've sent */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  lastsrtxcount ;      /*!< Transmit packet count when last SR sent */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  accumulated_transit ; 	/*!< accumulated a-dlsr-lsr */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  rtt ; 			/*!< Last reported rtt */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  reported_jitter ; 	/*!< The contents of their last jitter entry in the RR */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  reported_lost ; 	/*!< Reported lost packets in their RR */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  reported_maxjitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  reported_minjitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  reported_normdev_jitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  reported_stdev_jitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  reported_jitter_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  reported_maxlost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  reported_minlost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  reported_normdev_lost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  reported_stdev_lost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  rxlost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  maxrxlost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  minrxlost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  normdev_rxlost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  stdev_rxlost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  rxlost_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  maxrxjitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  minrxjitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  normdev_rxjitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  stdev_rxjitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  rxjitter_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  maxrtt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  minrtt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  normdevrtt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  stdevrtt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  rtt_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  rtp_red  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  t140 ;   /*!< Primary data  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  t140red ;    /*!< Redundant t140*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  pt [ AST_RED_MAX_GENERATION ] ;   /*!< Payload types for redundancy data */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  ts [ AST_RED_MAX_GENERATION ] ;  /*!< Time stamps */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  len [ AST_RED_MAX_GENERATION ] ;  /*!< length of each generation */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  num_gen ;  /*!< Number of generations */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  schedid ;  /*!< Timer id */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  ti ;  /*!< How long to buffer data before send */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  t140red_data [ 64000 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  buf_data [ 64000 ] ;  /*!< buffered primary data */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  hdrlen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									long  int  prev_ts ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* Forward Declarations */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_new ( struct  ast_rtp_instance  * instance ,  struct  sched_context  * sched ,  struct  sockaddr_in  * sin ,  void  * data ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_destroy ( struct  ast_rtp_instance  * instance ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_dtmf_begin ( struct  ast_rtp_instance  * instance ,  char  digit ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_dtmf_end ( struct  ast_rtp_instance  * instance ,  char  digit ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  ast_rtp_new_source ( struct  ast_rtp_instance  * instance ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_write ( struct  ast_rtp_instance  * instance ,  struct  ast_frame  * frame ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_frame  * ast_rtp_read ( struct  ast_rtp_instance  * instance ,  int  rtcp ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  ast_rtp_prop_set ( struct  ast_rtp_instance  * instance ,  enum  ast_rtp_property  property ,  int  value ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_fd ( struct  ast_rtp_instance  * instance ,  int  rtcp ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  ast_rtp_remote_address_set ( struct  ast_rtp_instance  * instance ,  struct  sockaddr_in  * sin ) ;  
						 
					
						
							
								
									
										
										
										
											2009-06-18 15:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  ast_rtp_alt_remote_address_set ( struct  ast_rtp_instance  * instance ,  struct  sockaddr_in  * sin ) ;  
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  rtp_red_init ( struct  ast_rtp_instance  * instance ,  int  buffer_time ,  int  * payloads ,  int  generations ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtp_red_buffer ( struct  ast_rtp_instance  * instance ,  struct  ast_frame  * frame ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_local_bridge ( struct  ast_rtp_instance  * instance0 ,  struct  ast_rtp_instance  * instance1 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_get_stat ( struct  ast_rtp_instance  * instance ,  struct  ast_rtp_instance_stats  * stats ,  enum  ast_rtp_instance_stat  stat ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_dtmf_compatible ( struct  ast_channel  * chan0 ,  struct  ast_rtp_instance  * instance0 ,  struct  ast_channel  * chan1 ,  struct  ast_rtp_instance  * instance1 ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  ast_rtp_stun_request ( struct  ast_rtp_instance  * instance ,  struct  sockaddr_in  * suggestion ,  const  char  * username ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  ast_rtp_stop ( struct  ast_rtp_instance  * instance ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* RTP Engine Declaration */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_rtp_engine  asterisk_rtp_engine  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. name  =  " asterisk " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. new  =  ast_rtp_new , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. destroy  =  ast_rtp_destroy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. dtmf_begin  =  ast_rtp_dtmf_begin , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. dtmf_end  =  ast_rtp_dtmf_end , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. new_source  =  ast_rtp_new_source , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. write  =  ast_rtp_write , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. read  =  ast_rtp_read , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. prop_set  =  ast_rtp_prop_set , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. fd  =  ast_rtp_fd , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. remote_address_set  =  ast_rtp_remote_address_set , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-18 15:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. alt_remote_address_set  =  ast_rtp_alt_remote_address_set , 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									. red_init  =  rtp_red_init , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. red_buffer  =  rtp_red_buffer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. local_bridge  =  ast_rtp_local_bridge , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. get_stat  =  ast_rtp_get_stat , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. dtmf_compatible  =  ast_rtp_dtmf_compatible , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. stun_request  =  ast_rtp_stun_request , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. stop  =  ast_rtp_stop , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  int  rtp_debug_test_addr ( struct  sockaddr_in  * addr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! rtpdebug )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtpdebugaddr . sin_addr . s_addr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( ( ntohs ( rtpdebugaddr . sin_port )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     & &  ( rtpdebugaddr . sin_port  ! =  addr - > sin_port ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    | |  ( rtpdebugaddr . sin_addr . s_addr  ! =  addr - > sin_addr . s_addr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  inline  int  rtcp_debug_test_addr ( struct  sockaddr_in  * addr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! rtcpdebug )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtcpdebugaddr . sin_addr . s_addr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( ( ntohs ( rtcpdebugaddr . sin_port )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     & &  ( rtcpdebugaddr . sin_port  ! =  addr - > sin_port ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    | |  ( rtcpdebugaddr . sin_addr . s_addr  ! =  addr - > sin_addr . s_addr ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  rtp_get_rate ( format_t  subclass )  
						 
					
						
							
								
									
										
										
										
											2009-07-08 23:19:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ( subclass  = =  AST_FORMAT_G722 )  ?  8000  :  ast_format_rate ( subclass ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  unsigned  int  ast_rtcp_calc_interval ( struct  ast_rtp  * rtp )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*! \todo XXX Do a more reasonable calculation on this one
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  Look  in  RFC  3550  Section  A .7  for  an  example */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									interval  =  rtcpinterval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Calculate normal deviation */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  double  normdev_compute ( double  normdev ,  double  sample ,  unsigned  int  sample_count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									normdev  =  normdev  *  sample_count  +  sample ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sample_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  normdev  /  sample_count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  double  stddev_compute ( double  stddev ,  double  sample ,  double  normdev ,  double  normdev_curent ,  unsigned  int  sample_count )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  the  formula  check  http : //www.cs.umd.edu/~austinjp/constSD.pdf
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  sqrt (  ( sample_count * pow ( stddev , 2 )  +  sample_count * pow ( ( sample - normdev ) / ( sample_count + 1 ) , 2 )  +  pow ( sample - normdev_curent , 2 ) )  /  ( sample_count + 1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										we  can  compute  the  sigma ^ 2  and  that  way  we  would  have  to  do  the  sqrt  only  1  time  at  the  end  and  would  save  another  pow  2  compute 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										optimized  formula 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define SQUARE(x) ((x) * (x)) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									stddev  =  sample_count  *  stddev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sample_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  stddev  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										(  sample_count  *  SQUARE (  ( sample  -  normdev )  /  sample_count  )  )  + 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										(  SQUARE ( sample  -  normdev_curent )  /  sample_count  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef SQUARE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  create_new_socket ( const  char  * type )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  sock  =  socket ( AF_INET ,  SOCK_DGRAM ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( sock  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											type  =  " RTP/RTCP " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Unable to allocate %s socket: %s \n " ,  type ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										long  flags  =  fcntl ( sock ,  F_GETFL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fcntl ( sock ,  F_SETFL ,  flags  |  O_NONBLOCK ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef SO_NO_CHECK 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( nochecksums )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											setsockopt ( sock ,  SOL_SOCKET ,  SO_NO_CHECK ,  & nochecksums ,  sizeof ( nochecksums ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  sock ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_new ( struct  ast_rtp_instance  * instance ,  struct  sched_context  * sched ,  struct  sockaddr_in  * sin ,  void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  x ,  startplace ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Create a new RTP structure to hold all of our data */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( rtp  =  ast_calloc ( 1 ,  sizeof ( * rtp ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Set default parameters on the newly created RTP structure */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > ssrc  =  ast_random ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > seqno  =  ast_random ( )  &  0xffff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > strict_rtp_state  =  ( strictrtp  ?  STRICT_RTP_LEARN  :  STRICT_RTP_OPEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Create a new socket for us to listen on and use */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( rtp - > s  =  create_new_socket ( " RTP " ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Failed to create a new socket for RTP instance '%p' \n " ,  instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_free ( rtp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Now actually find a free RTP port to use */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									x  =  ( rtpend  = =  rtpstart )  ?  rtpstart  :  ( ast_random ( )  %  ( rtpend  -  rtpstart ) )  +  rtpstart ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									x  =  x  &  ~ 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									startplace  =  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 18:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sin - > sin_port  =  htons ( x ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Try to bind, this will tell us whether the port is available or not */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 18:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! bind ( rtp - > s ,  ( struct  sockaddr  * ) sin ,  sizeof ( * sin ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Allocated port %d for RTP instance '%p' \n " ,  x ,  instance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 18:14:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_rtp_instance_set_local_address ( instance ,  sin ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										x  + =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( x  >  rtpend )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											x  =  ( rtpstart  +  1 )  &  ~ 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* See if we ran out of ports or if the bind actually failed because of something other than the address being in use */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( x  = =  startplace  | |  errno  ! =  EADDRINUSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " Oh dear... we couldn't allocate a port for RTP instance '%p' \n " ,  instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Record any information we may need */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > sched  =  sched ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Associate the RTP structure with the RTP instance and be done */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rtp_instance_set_data ( instance ,  rtp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_destroy ( struct  ast_rtp_instance  * instance )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Destroy the smoother that was smoothing out audio if present */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > smoother )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_smoother_free ( rtp - > smoother ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Close our own socket so we no longer get packets */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > s  >  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( rtp - > s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Destroy RTCP if it was being used */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > rtcp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_SCHED_DEL ( rtp - > sched ,  rtp - > rtcp - > schedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										close ( rtp - > rtcp - > s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_free ( rtp - > rtcp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Destroy RED if it was being used */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > red )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_SCHED_DEL ( rtp - > sched ,  rtp - > red - > schedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_free ( rtp - > red ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Finally destroy ourselves */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( rtp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_dtmf_begin ( struct  ast_rtp_instance  * instance ,  char  digit )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 18:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sockaddr_in  remote_address  =  {  0 ,  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  hdrlen  =  12 ,  res  =  0 ,  i  =  0 ,  payload  =  101 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  data [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  * rtpheader  =  ( unsigned  int * ) data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rtp_instance_get_remote_address ( instance ,  & remote_address ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If we have no remote address information bail out now */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! remote_address . sin_addr . s_addr  | |  ! remote_address . sin_port )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Convert given digit into what we want to transmit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( digit  < =  ' 9 ' )  & &  ( digit  > =  ' 0 ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										digit  - =  ' 0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( digit  = =  ' * ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										digit  =  10 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( digit  = =  ' # ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										digit  =  11 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ( digit  > =  ' A ' )  & &  ( digit  < =  ' D ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										digit  =  digit  -  ' A '  +  12 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ( digit  > =  ' a ' )  & &  ( digit  < =  ' d ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										digit  =  digit  -  ' a '  +  12 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Don't know how to represent '%c' \n " ,  digit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Grab the payload that they expect the RFC2833 packet to be received in */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									payload  =  ast_rtp_codecs_payload_code ( ast_rtp_instance_get_codecs ( instance ) ,  0 ,  AST_RTP_DTMF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > dtmfmute  =  ast_tvadd ( ast_tvnow ( ) ,  ast_tv ( 0 ,  500000 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > send_duration  =  160 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > lastdigitts  =  rtp - > lastts  +  rtp - > send_duration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Create the actual packet that we will be sending */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 0 ]  =  htonl ( ( 2  < <  30 )  |  ( 1  < <  23 )  |  ( payload  < <  16 )  |  ( rtp - > seqno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 1 ]  =  htonl ( rtp - > lastdigitts ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 2 ]  =  htonl ( rtp - > ssrc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Actually send the packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  2 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtpheader [ 3 ]  =  htonl ( ( digit  < <  24 )  |  ( 0xa  < <  16 )  |  ( rtp - > send_duration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  sendto ( rtp - > s ,  ( void  * )  rtpheader ,  hdrlen  +  4 ,  0 ,  ( struct  sockaddr  * )  & remote_address ,  sizeof ( remote_address ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " RTP Transmission error to %s:%u: %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_inet_ntoa ( remote_address . sin_addr ) ,  ntohs ( remote_address . sin_port ) ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rtp_debug_test_addr ( & remote_address ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verbose ( " Sent RTP DTMF packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    ast_inet_ntoa ( remote_address . sin_addr ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    ntohs ( remote_address . sin_port ) ,  payload ,  rtp - > seqno ,  rtp - > lastdigitts ,  res  -  hdrlen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > seqno + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > send_duration  + =  160 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtpheader [ 0 ]  =  htonl ( ( 2  < <  30 )  |  ( payload  < <  16 )  |  ( rtp - > seqno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Record that we are in the process of sending a digit and information needed to continue doing so */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > sending_digit  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > send_digit  =  digit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > send_payload  =  payload ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_dtmf_continuation ( struct  ast_rtp_instance  * instance )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 18:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sockaddr_in  remote_address  =  {  0 ,  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  hdrlen  =  12 ,  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  data [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  * rtpheader  =  ( unsigned  int * ) data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rtp_instance_get_remote_address ( instance ,  & remote_address ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Make sure we know where the other side is so we can send them the packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! remote_address . sin_addr . s_addr  | |  ! remote_address . sin_port )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Actually create the packet we will be sending */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 0 ]  =  htonl ( ( 2  < <  30 )  |  ( 1  < <  23 )  |  ( rtp - > send_payload  < <  16 )  |  ( rtp - > seqno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 1 ]  =  htonl ( rtp - > lastdigitts ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 2 ]  =  htonl ( rtp - > ssrc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 3 ]  =  htonl ( ( rtp - > send_digit  < <  24 )  |  ( 0xa  < <  16 )  |  ( rtp - > send_duration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 0 ]  =  htonl ( ( 2  < <  30 )  |  ( rtp - > send_payload  < <  16 )  |  ( rtp - > seqno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Boom, send it on out */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  sendto ( rtp - > s ,  ( void  * )  rtpheader ,  hdrlen  +  4 ,  0 ,  ( struct  sockaddr  * )  & remote_address ,  sizeof ( remote_address ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " RTP Transmission error to %s:%d: %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_inet_ntoa ( remote_address . sin_addr ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ntohs ( remote_address . sin_port ) ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp_debug_test_addr ( & remote_address ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( " Sent RTP DTMF packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    ast_inet_ntoa ( remote_address . sin_addr ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    ntohs ( remote_address . sin_port ) ,  rtp - > send_payload ,  rtp - > seqno ,  rtp - > lastdigitts ,  res  -  hdrlen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* And now we increment some values for the next time we swing by */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > seqno + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > send_duration  + =  160 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_dtmf_end ( struct  ast_rtp_instance  * instance ,  char  digit )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 18:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sockaddr_in  remote_address  =  {  0 ,  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  hdrlen  =  12 ,  res  =  0 ,  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  data [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  * rtpheader  =  ( unsigned  int * ) data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rtp_instance_get_remote_address ( instance ,  & remote_address ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Make sure we know where the remote side is so we can send them the packet we construct */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! remote_address . sin_addr . s_addr  | |  ! remote_address . sin_port )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Convert the given digit to the one we are going to send */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( digit  < =  ' 9 ' )  & &  ( digit  > =  ' 0 ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										digit  - =  ' 0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( digit  = =  ' * ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										digit  =  10 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( digit  = =  ' # ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										digit  =  11 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ( digit  > =  ' A ' )  & &  ( digit  < =  ' D ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										digit  =  digit  -  ' A '  +  12 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ( digit  > =  ' a ' )  & &  ( digit  < =  ' d ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										digit  =  digit  -  ' a '  +  12 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Don't know how to represent '%c' \n " ,  digit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > dtmfmute  =  ast_tvadd ( ast_tvnow ( ) ,  ast_tv ( 0 ,  500000 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Construct the packet we are going to send */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 0 ]  =  htonl ( ( 2  < <  30 )  |  ( 1  < <  23 )  |  ( rtp - > send_payload  < <  16 )  |  ( rtp - > seqno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 1 ]  =  htonl ( rtp - > lastdigitts ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 2 ]  =  htonl ( rtp - > ssrc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 3 ]  =  htonl ( ( digit  < <  24 )  |  ( 0xa  < <  16 )  |  ( rtp - > send_duration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 3 ]  | =  htonl ( ( 1  < <  23 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 0 ]  =  htonl ( ( 2  < <  30 )  |  ( rtp - > send_payload  < <  16 )  |  ( rtp - > seqno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Send it 3 times, that's the magical number */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  3 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  sendto ( rtp - > s ,  ( void  * )  rtpheader ,  hdrlen  +  4 ,  0 ,  ( struct  sockaddr  * )  & remote_address ,  sizeof ( remote_address ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " RTP Transmission error to %s:%d: %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_inet_ntoa ( remote_address . sin_addr ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ntohs ( remote_address . sin_port ) ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rtp_debug_test_addr ( & remote_address ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verbose ( " Sent RTP DTMF packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    ast_inet_ntoa ( remote_address . sin_addr ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    ntohs ( remote_address . sin_port ) ,  rtp - > send_payload ,  rtp - > seqno ,  rtp - > lastdigitts ,  res  -  hdrlen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Oh and we can't forget to turn off the stuff that says we are sending DTMF */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > lastts  + =  rtp - > send_duration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > sending_digit  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > send_digit  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  ast_rtp_new_source ( struct  ast_rtp_instance  * instance )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* We simply set this bit so that the next packet sent will have the marker bit turned on */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_set_flag ( rtp ,  FLAG_NEED_MARKER_BIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-30 18:21:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ast_rtp_instance_get_prop ( instance ,  AST_RTP_PROPERTY_CONSTANT_SSRC ) )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 221086 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
  r221086 | twilson | 2009-09-30 09:49:11 -0500 (Wed, 30 Sep 2009) | 25 lines
  
  Change the SSRC by default when our media stream changes
  
  Be default, change SSRC when doing an audio stream changes Asterisk doesn't
  honor marker bit when reinvited to already-bridged RTP streams,resulting in
  far-end stack discarding packets with "old" timestamps that areactually part of
  a new stream.  This patch sends AST_CONTROL_SRCUPDATE whenever there is a
  reinvite, unless the 'constantssrc' is set to true in sip.conf.
  
  The original issue reported to Digium support detailed the following situation:
  ITSP <-> Asterisk 1.4.26.2 <-> SIP-based Application Server Call comes in
  fromITSP, Asterisk dials the app server which sends a re-invite back
  toAsterisk--not to negotiate to send media directly to the ITSP, but to
  indicatethat it's changing the stream it's sending to Asterisk.  The app
  servergenerates a new SSRC, sequence numbers, timestamps, and sets the marker
  bit on the new stream.  Asterisk passes through the teimstamp of the new stream,
  butdoes not reset the SSRC, sequence numbers, or set the marker bit.
  
  When the timestamp on the new stream is older than the timestamp on the
  originalstream, the ITSP (which doesn't know there has been any change) discards
  the newframes because it thinks they are too old.  This patch addresses this by
  changing the SSRC on a stream update unless constantssrc=true is set in
  sip.conf.
  
  Review: https://reviewboard.asterisk.org/r/374/
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@221266 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-09-30 17:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtp - > ssrc  =  ast_random ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  unsigned  int  calc_txstamp ( struct  ast_rtp  * rtp ,  struct  timeval  * delivery )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  timeval  t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									long  ms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_tvzero ( rtp - > txcore ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > txcore  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > txcore . tv_usec  - =  rtp - > txcore . tv_usec  %  20000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									t  =  ( delivery  & &  ! ast_tvzero ( * delivery ) )  ?  * delivery  :  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( ms  =  ast_tvdiff_ms ( t ,  rtp - > txcore ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ms  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > txcore  =  t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ( unsigned  int )  ms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  timeval2ntp ( struct  timeval  tv ,  unsigned  int  * msw ,  unsigned  int  * lsw )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  sec ,  usec ,  frac ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									sec  =  tv . tv_sec  +  2208988800u ;  /* Sec between 1900 and 1970 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									usec  =  tv . tv_usec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									frac  =  ( usec  < <  12 )  +  ( usec  < <  8 )  -  ( ( usec  *  3650 )  > >  6 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* msw  =  sec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* lsw  =  frac ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Send RTCP recipient's report */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtcp_write_rr ( const  void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ( struct  ast_rtp  * ) data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  len  =  32 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  lost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  extended ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  expected ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  expected_interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  received_interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  lost_interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  timeval  now ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  * rtcpheader ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  bdata [ 1024 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  timeval  dlsr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  fraction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  rxlost_current ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! rtp  | |  ! rtp - > rtcp  | |  ( & rtp - > rtcp - > them . sin_addr  = =  0 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! rtp - > rtcp - > them . sin_addr . s_addr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " RTCP RR transmission error, rtcp halted \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_SCHED_DEL ( rtp - > sched ,  rtp - > rtcp - > schedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									extended  =  rtp - > cycles  +  rtp - > lastrxseqno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									expected  =  extended  -  rtp - > seedrxseqno  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lost  =  expected  -  rtp - > rxcount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									expected_interval  =  expected  -  rtp - > rtcp - > expected_prior ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rtcp - > expected_prior  =  expected ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									received_interval  =  rtp - > rxcount  -  rtp - > rtcp - > received_prior ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rtcp - > received_prior  =  rtp - > rxcount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lost_interval  =  expected_interval  -  received_interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( lost_interval  < =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > rtcp - > rxlost  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else  rtp - > rtcp - > rxlost  =  rtp - > rtcp - > rxlost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > rtcp - > rxlost_count  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > rtcp - > minrxlost  =  rtp - > rtcp - > rxlost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( lost_interval  <  rtp - > rtcp - > minrxlost ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > rtcp - > minrxlost  =  rtp - > rtcp - > rxlost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( lost_interval  >  rtp - > rtcp - > maxrxlost ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > rtcp - > maxrxlost  =  rtp - > rtcp - > rxlost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rxlost_current  =  normdev_compute ( rtp - > rtcp - > normdev_rxlost ,  rtp - > rtcp - > rxlost ,  rtp - > rtcp - > rxlost_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rtcp - > stdev_rxlost  =  stddev_compute ( rtp - > rtcp - > stdev_rxlost ,  rtp - > rtcp - > rxlost ,  rtp - > rtcp - > normdev_rxlost ,  rxlost_current ,  rtp - > rtcp - > rxlost_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rtcp - > normdev_rxlost  =  rxlost_current ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rtcp - > rxlost_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( expected_interval  = =  0  | |  lost_interval  < =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fraction  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fraction  =  ( lost_interval  < <  8 )  /  expected_interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gettimeofday ( & now ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									timersub ( & now ,  & rtp - > rtcp - > rxlsr ,  & dlsr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader  =  ( unsigned  int  * ) bdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 0 ]  =  htonl ( ( 2  < <  30 )  |  ( 1  < <  24 )  |  ( RTCP_PT_RR  < <  16 )  |  ( ( len / 4 ) - 1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 1 ]  =  htonl ( rtp - > ssrc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 2 ]  =  htonl ( rtp - > themssrc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 3 ]  =  htonl ( ( ( fraction  &  0xff )  < <  24 )  |  ( lost  &  0xffffff ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 4 ]  =  htonl ( ( rtp - > cycles )  |  ( ( rtp - > lastrxseqno  &  0xffff ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 5 ]  =  htonl ( ( unsigned  int ) ( rtp - > rxjitter  *  65536. ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 6 ]  =  htonl ( rtp - > rtcp - > themrxlsr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 7 ]  =  htonl ( ( ( ( dlsr . tv_sec  *  1000 )  +  ( dlsr . tv_usec  /  1000 ) )  *  65536 )  /  1000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*! \note Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									  it  can  change  mid  call ,  and  SDES  can ' t )  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ len / 4 ]      =  htonl ( ( 2  < <  30 )  |  ( 1  < <  24 )  |  ( RTCP_PT_SDES  < <  16 )  |  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ ( len / 4 ) + 1 ]  =  htonl ( rtp - > ssrc ) ;                /* Our SSRC */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ ( len / 4 ) + 2 ]  =  htonl ( 0x01  < <  24 ) ;               /* Empty for the moment */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									len  + =  12 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  sendto ( rtp - > rtcp - > s ,  ( unsigned  int  * ) rtcpheader ,  len ,  0 ,  ( struct  sockaddr  * ) & rtp - > rtcp - > them ,  sizeof ( rtp - > rtcp - > them ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " RTCP RR transmission error, rtcp halted: %s \n " , strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Remove the scheduler */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_SCHED_DEL ( rtp - > sched ,  rtp - > rtcp - > schedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rtcp - > rr_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtcp_debug_test_addr ( & rtp - > rtcp - > them ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( " \n * Sending RTCP RR to %s:%d \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"   Our SSRC: %u \n Their SSRC: %u \n iFraction lost: %d \n Cumulative loss: %u \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"   IA jitter: %.4f \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"   Their last SR: %u \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    "   DLSR: %4.4f (sec) \n \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    ast_inet_ntoa ( rtp - > rtcp - > them . sin_addr ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    ntohs ( rtp - > rtcp - > them . sin_port ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    rtp - > ssrc ,  rtp - > themssrc ,  fraction ,  lost , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    rtp - > rxjitter , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    rtp - > rtcp - > themrxlsr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    ( double ) ( ntohl ( rtcpheader [ 7 ] ) / 65536.0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Send RTCP sender's report */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtcp_write_sr ( const  void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ( struct  ast_rtp  * ) data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  timeval  now ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  now_lsw ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  now_msw ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  * rtcpheader ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  lost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  extended ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  expected ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  expected_interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  received_interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  lost_interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  fraction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  timeval  dlsr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  bdata [ 512 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Commented condition is always not NULL if rtp->rtcp is not NULL */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! rtp  | |  ! rtp - > rtcp /* || (&rtp->rtcp->them.sin_addr == 0)*/ ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! rtp - > rtcp - > them . sin_addr . s_addr )  {   /* This'll stop rtcp for this rtp session */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( " RTCP SR transmission error, rtcp halted \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_SCHED_DEL ( rtp - > sched ,  rtp - > rtcp - > schedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gettimeofday ( & now ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									timeval2ntp ( now ,  & now_msw ,  & now_lsw ) ;  /* fill thses ones in from utils.c*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader  =  ( unsigned  int  * ) bdata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 1 ]  =  htonl ( rtp - > ssrc ) ;                /* Our SSRC */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 2 ]  =  htonl ( now_msw ) ;                  /* now, MSW. gettimeofday() + SEC_BETWEEN_1900_AND_1970*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 3 ]  =  htonl ( now_lsw ) ;                  /* now, LSW */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 4 ]  =  htonl ( rtp - > lastts ) ;              /* FIXME shouldn't be that, it should be now */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 5 ]  =  htonl ( rtp - > txcount ) ;             /* No. packets sent */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 6 ]  =  htonl ( rtp - > txoctetcount ) ;        /* No. bytes sent */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									len  + =  28 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									extended  =  rtp - > cycles  +  rtp - > lastrxseqno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									expected  =  extended  -  rtp - > seedrxseqno  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > rxcount  >  expected ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										expected  + =  rtp - > rxcount  -  expected ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lost  =  expected  -  rtp - > rxcount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									expected_interval  =  expected  -  rtp - > rtcp - > expected_prior ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rtcp - > expected_prior  =  expected ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									received_interval  =  rtp - > rxcount  -  rtp - > rtcp - > received_prior ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rtcp - > received_prior  =  rtp - > rxcount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lost_interval  =  expected_interval  -  received_interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( expected_interval  = =  0  | |  lost_interval  < =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fraction  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fraction  =  ( lost_interval  < <  8 )  /  expected_interval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									timersub ( & now ,  & rtp - > rtcp - > rxlsr ,  & dlsr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 7 ]  =  htonl ( rtp - > themssrc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 8 ]  =  htonl ( ( ( fraction  &  0xff )  < <  24 )  |  ( lost  &  0xffffff ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 9 ]  =  htonl ( ( rtp - > cycles )  |  ( ( rtp - > lastrxseqno  &  0xffff ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 10 ]  =  htonl ( ( unsigned  int ) ( rtp - > rxjitter  *  65536. ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 11 ]  =  htonl ( rtp - > rtcp - > themrxlsr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 12 ]  =  htonl ( ( ( ( dlsr . tv_sec  *  1000 )  +  ( dlsr . tv_usec  /  1000 ) )  *  65536 )  /  1000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									len  + =  24 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ 0 ]  =  htonl ( ( 2  < <  30 )  |  ( 1  < <  24 )  |  ( RTCP_PT_SR  < <  16 )  |  ( ( len / 4 ) - 1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* it can change mid call, and SDES can't) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ len / 4 ]      =  htonl ( ( 2  < <  30 )  |  ( 1  < <  24 )  |  ( RTCP_PT_SDES  < <  16 )  |  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ ( len / 4 ) + 1 ]  =  htonl ( rtp - > ssrc ) ;                /* Our SSRC */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpheader [ ( len / 4 ) + 2 ]  =  htonl ( 0x01  < <  24 ) ;                     /* Empty for the moment */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									len  + =  12 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  sendto ( rtp - > rtcp - > s ,  ( unsigned  int  * ) rtcpheader ,  len ,  0 ,  ( struct  sockaddr  * ) & rtp - > rtcp - > them ,  sizeof ( rtp - > rtcp - > them ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " RTCP SR transmission error to %s:%d, rtcp halted %s \n " , ast_inet_ntoa ( rtp - > rtcp - > them . sin_addr ) ,  ntohs ( rtp - > rtcp - > them . sin_port ) ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_SCHED_DEL ( rtp - > sched ,  rtp - > rtcp - > schedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* FIXME Don't need to get a new one */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gettimeofday ( & rtp - > rtcp - > txlsr ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rtcp - > sr_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rtcp - > lastsrtxcount  =  rtp - > txcount ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtcp_debug_test_addr ( & rtp - > rtcp - > them ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( " * Sent RTCP SR to %s:%d \n " ,  ast_inet_ntoa ( rtp - > rtcp - > them . sin_addr ) ,  ntohs ( rtp - > rtcp - > them . sin_port ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( "   Our SSRC: %u \n " ,  rtp - > ssrc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( "   Sent(NTP): %u.%010u \n " ,  ( unsigned  int ) now . tv_sec ,  ( unsigned  int ) now . tv_usec * 4096 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( "   Sent(RTP): %u \n " ,  rtp - > lastts ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( "   Sent packets: %u \n " ,  rtp - > txcount ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( "   Sent octets: %u \n " ,  rtp - > txoctetcount ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( "   Report block: \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( "   Fraction lost: %u \n " ,  fraction ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( "   Cumulative loss: %u \n " ,  lost ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( "   IA jitter: %.4f \n " ,  rtp - > rxjitter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( "   Their last SR: %u \n " ,  rtp - > rtcp - > themrxlsr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( "   DLSR: %4.4f (sec) \n \n " ,  ( double ) ( ntohl ( rtcpheader [ 12 ] ) / 65536.0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									manager_event ( EVENT_FLAG_REPORTING ,  " RTCPSent " ,  " To %s:%d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    " OurSSRC: %u \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    " SentNTP: %u.%010u \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    " SentRTP: %u \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    " SentPackets: %u \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    " SentOctets: %u \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    " ReportBlock: \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    " FractionLost: %u \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    " CumulativeLoss: %u \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    " IAJitter: %.4f \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													    " TheirLastSR: %u \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      " DLSR: %4.4f (sec) \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      ast_inet_ntoa ( rtp - > rtcp - > them . sin_addr ) ,  ntohs ( rtp - > rtcp - > them . sin_port ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      rtp - > ssrc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      ( unsigned  int ) now . tv_sec ,  ( unsigned  int ) now . tv_usec * 4096 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      rtp - > lastts , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      rtp - > txcount , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      rtp - > txoctetcount , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      fraction , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      lost , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      rtp - > rxjitter , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      rtp - > rtcp - > themrxlsr , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										      ( double ) ( ntohl ( rtcpheader [ 12 ] ) / 65536.0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Write and RTCP packet to the far end
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note  Decide  if  we  are  going  to  send  an  SR  ( with  Reception  Block )  or  RR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  RR  is  sent  if  we  have  not  sent  any  rtp  packets  in  the  previous  interval  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtcp_write ( const  void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ( struct  ast_rtp  * ) data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! rtp  | |  ! rtp - > rtcp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > txcount  >  rtp - > rtcp - > lastsrtxcount ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  ast_rtcp_write_sr ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  ast_rtcp_write_rr ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_raw_write ( struct  ast_rtp_instance  * instance ,  struct  ast_frame  * frame ,  int  codec )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  pred ,  mark  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  ms  =  calc_txstamp ( rtp ,  & frame - > delivery ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 18:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sockaddr_in  remote_address  =  {  0 ,  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  rate  =  rtp_get_rate ( frame - > subclass . codec )  /  1000 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-08 23:19:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( frame - > subclass . codec  = =  AST_FORMAT_G722 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-08 23:19:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										frame - > samples  / =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > sending_digit )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( frame - > frametype  = =  AST_FRAME_VOICE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pred  =  rtp - > lastts  +  frame - > samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Re-calculate last TS */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-08 23:19:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtp - > lastts  =  rtp - > lastts  +  ms  *  rate ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( ast_tvzero ( frame - > delivery ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* If this isn't an absolute delivery time, Check if it is close to our prediction,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   and  if  so ,  go  with  our  prediction  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( abs ( rtp - > lastts  -  pred )  <  MAX_TIMESTAMP_SKEW )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > lastts  =  pred ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 3 ,  " Difference is %d, ms is %d \n " ,  abs ( rtp - > lastts  -  pred ) ,  ms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												mark  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( frame - > frametype  = =  AST_FRAME_VIDEO )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										mark  =  frame - > subclass . codec  &  0x1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										pred  =  rtp - > lastovidtimestamp  +  frame - > samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Re-calculate last TS */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > lastts  =  rtp - > lastts  +  ms  *  90 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* If it's close to our prediction, go for it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_tvzero ( frame - > delivery ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( abs ( rtp - > lastts  -  pred )  <  7200 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > lastts  =  pred ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > lastovidtimestamp  + =  frame - > samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 3 ,  " Difference is %d, ms is %d (%d), pred/ts/samples %d/%d/%d \n " ,  abs ( rtp - > lastts  -  pred ) ,  ms ,  ms  *  90 ,  rtp - > lastts ,  pred ,  frame - > samples ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > lastovidtimestamp  =  rtp - > lastts ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pred  =  rtp - > lastotexttimestamp  +  frame - > samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Re-calculate last TS */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-14 17:40:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtp - > lastts  =  rtp - > lastts  +  ms ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* If it's close to our prediction, go for it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_tvzero ( frame - > delivery ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( abs ( rtp - > lastts  -  pred )  <  7200 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > lastts  =  pred ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > lastotexttimestamp  + =  frame - > samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-14 17:40:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 3 ,  " Difference is %d, ms is %d, pred/ts/samples %d/%d/%d \n " ,  abs ( rtp - > lastts  -  pred ) ,  ms ,  rtp - > lastts ,  pred ,  frame - > samples ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												rtp - > lastotexttimestamp  =  rtp - > lastts ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If we have been explicitly told to set the marker bit then do so */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_test_flag ( rtp ,  FLAG_NEED_MARKER_BIT ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mark  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_clear_flag ( rtp ,  FLAG_NEED_MARKER_BIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If the timestamp for non-digt packets has moved beyond the timestamp for digits, update the digit timestamp */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > lastts  >  rtp - > lastdigitts )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > lastdigitts  =  rtp - > lastts ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_test_flag ( frame ,  AST_FRFLAG_HAS_TIMING_INFO ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-08 23:19:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtp - > lastts  =  frame - > ts  *  rate ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rtp_instance_get_remote_address ( instance ,  & remote_address ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If we know the remote address construct a packet and send it out */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( remote_address . sin_port  & &  remote_address . sin_addr . s_addr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  hdrlen  =  12 ,  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unsigned  char  * rtpheader  =  ( unsigned  char  * ) ( frame - > data . ptr  -  hdrlen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										put_unaligned_uint32 ( rtpheader ,  htonl ( ( 2  < <  30 )  |  ( codec  < <  16 )  |  ( rtp - > seqno )  |  ( mark  < <  23 ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										put_unaligned_uint32 ( rtpheader  +  4 ,  htonl ( rtp - > lastts ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										put_unaligned_uint32 ( rtpheader  +  8 ,  htonl ( rtp - > ssrc ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( res  =  sendto ( rtp - > s ,  ( void  * ) rtpheader ,  frame - > datalen  +  hdrlen ,  0 ,  ( struct  sockaddr  * ) & remote_address ,  sizeof ( remote_address ) ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ast_rtp_instance_get_prop ( instance ,  AST_RTP_PROPERTY_NAT )  | |  ( ast_rtp_instance_get_prop ( instance ,  AST_RTP_PROPERTY_NAT )  & &  ( ast_test_flag ( rtp ,  FLAG_NAT_ACTIVE )  = =  FLAG_NAT_ACTIVE ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " RTP Transmission error of packet %d to %s:%d: %s \n " ,  rtp - > seqno ,  ast_inet_ntoa ( remote_address . sin_addr ) ,  ntohs ( remote_address . sin_port ) ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( ( ( ast_test_flag ( rtp ,  FLAG_NAT_ACTIVE )  = =  FLAG_NAT_INACTIVE )  | |  rtpdebug )  & &  ! ast_test_flag ( rtp ,  FLAG_NAT_INACTIVE_NOWARN ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Only give this error message once if we are not RTP debugging */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( option_debug  | |  rtpdebug ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 0 ,  " RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio... \n " ,  ast_inet_ntoa ( remote_address . sin_addr ) ,  ntohs ( remote_address . sin_port ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_set_flag ( rtp ,  FLAG_NAT_INACTIVE_NOWARN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > txcount + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > txoctetcount  + =  ( res  -  hdrlen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtp - > rtcp  & &  rtp - > rtcp - > schedid  <  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Starting RTCP transmission on RTP instance '%p' \n " ,  instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > rtcp - > schedid  =  ast_sched_add ( rtp - > sched ,  ast_rtcp_calc_interval ( rtp ) ,  ast_rtcp_write ,  rtp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rtp_debug_test_addr ( & remote_address ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verbose ( " Sent RTP packet to      %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												    ast_inet_ntoa ( remote_address . sin_addr ) ,  ntohs ( remote_address . sin_port ) ,  codec ,  rtp - > seqno ,  rtp - > lastts ,  res  -  hdrlen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > seqno + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_frame  * red_t140_to_red ( struct  rtp_red  * red )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  * data  =  red - > t140red . data . ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* replace most aged generation */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( red - > len [ 0 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( i  =  1 ;  i  <  red - > num_gen + 1 ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											len  + =  red - > len [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memmove ( & data [ red - > hdrlen ] ,  & data [ red - > hdrlen + red - > len [ 0 ] ] ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Store length of each generation and primary data length*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  red - > num_gen ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										red - > len [ i ]  =  red - > len [ i + 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									red - > len [ i ]  =  red - > t140 . datalen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* write each generation length in red header */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									len  =  red - > hdrlen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  red - > num_gen ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										len  + =  data [ i * 4 + 3 ]  =  red - > len [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* add primary data to buffer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memcpy ( & data [ len ] ,  red - > t140 . data . ptr ,  red - > t140 . datalen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									red - > t140red . datalen  =  len  +  red - > t140 . datalen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* no primary data and no generations to send */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( len  = =  red - > hdrlen  & &  ! red - > t140 . datalen ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* reset t.140 buffer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									red - > t140 . datalen  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & red - > t140red ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_write ( struct  ast_rtp_instance  * instance ,  struct  ast_frame  * frame )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 18:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sockaddr_in  remote_address  =  {  0 ,  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									format_t  codec ,  subclass ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rtp_instance_get_remote_address ( instance ,  & remote_address ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If we don't actually know the remote address don't even bother doing anything */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! remote_address . sin_addr . s_addr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " No remote address on RTP instance '%p' so dropping frame \n " ,  instance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 16:27:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If there is no data length we can't very well send the packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! frame - > datalen )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Received frame with no data for RTP instance '%p' so dropping frame \n " ,  instance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 16:27:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If the packet is not one our RTP stack supports bail out */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( frame - > frametype  ! =  AST_FRAME_VOICE  & &  frame - > frametype  ! =  AST_FRAME_VIDEO  & &  frame - > frametype  ! =  AST_FRAME_TEXT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " RTP can only send voice, video, and text \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > red )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* return 0; */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* no primary data or generations to send */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( frame  =  red_t140_to_red ( rtp - > red ) )  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Grab the subclass and look up the payload we are going to use */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									subclass  =  frame - > subclass . codec ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( frame - > frametype  = =  AST_FRAME_VIDEO )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										subclass  & =  ~ 0x1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( codec  =  ast_rtp_codecs_payload_code ( ast_rtp_instance_get_codecs ( instance ) ,  1 ,  subclass ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Don't know how to send format %s packets with RTP \n " ,  ast_getformatname ( frame - > subclass . codec ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Oh dear, if the format changed we will have to set up a new smoother */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > lasttxformat  ! =  subclass )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Ooh, format changed from %s to %s \n " ,  ast_getformatname ( rtp - > lasttxformat ) ,  ast_getformatname ( subclass ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > lasttxformat  =  subclass ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rtp - > smoother )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_smoother_free ( rtp - > smoother ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > smoother  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If no smoother is present see if we have to set one up */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! rtp - > smoother )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_format_list  fmt  =  ast_codec_pref_getsize ( & ast_rtp_instance_get_codecs ( instance ) - > pref ,  subclass ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( subclass )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AST_FORMAT_SPEEX : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AST_FORMAT_G723_1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AST_FORMAT_SIREN7 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AST_FORMAT_SIREN14 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* these are all frame-based codecs and cannot be safely run through
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   a  smoother  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( fmt . inc_ms )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! ( rtp - > smoother  =  ast_smoother_new ( ( fmt . cur_ms  *  fmt . fr_len )  /  fmt . inc_ms ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Unable to create smoother: format %s ms: %d len: %d \n " ,  ast_getformatname ( subclass ) ,  fmt . cur_ms ,  ( ( fmt . cur_ms  *  fmt . fr_len )  /  fmt . inc_ms ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( fmt . flags )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_smoother_set_flags ( rtp - > smoother ,  fmt . flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Created smoother: format: %s ms: %d len: %d \n " ,  ast_getformatname ( subclass ) ,  fmt . cur_ms ,  ( ( fmt . cur_ms  *  fmt . fr_len )  /  fmt . inc_ms ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Feed audio frames into the actual function that will create a frame and send it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > smoother )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_frame  * f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_smoother_test_flag ( rtp - > smoother ,  AST_SMOOTHER_FLAG_BE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_smoother_feed_be ( rtp - > smoother ,  frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_smoother_feed ( rtp - > smoother ,  frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( ( f  =  ast_smoother_read ( rtp - > smoother ) )  & &  ( f - > data . ptr ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-08 23:19:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_rtp_raw_write ( instance ,  f ,  codec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  hdrlen  =  12 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_frame  * f  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( frame - > offset  <  hdrlen )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f  =  ast_frdup ( frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f  =  frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( f - > data . ptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_rtp_raw_write ( instance ,  f ,  codec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( f  ! =  frame )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-19 23:47:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  sanitize_tv ( struct  timeval  * tv )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( tv - > tv_usec  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tv - > tv_usec  + =  1000000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tv - > tv_sec  - =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( tv - > tv_usec  > =  1000000 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tv - > tv_usec  - =  1000000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tv - > tv_sec  + =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  void  calc_rxstamp ( struct  timeval  * tv ,  struct  ast_rtp  * rtp ,  unsigned  int  timestamp ,  int  mark )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  timeval  now ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  transit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  current_time ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  dtv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  prog ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  rate  =  rtp_get_rate ( rtp - > f . subclass . codec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									double  normdev_rxjitter_current ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( ! rtp - > rxcore . tv_sec  & &  ! rtp - > rxcore . tv_usec )  | |  mark )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										gettimeofday ( & rtp - > rxcore ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > drxcore  =  ( double )  rtp - > rxcore . tv_sec  +  ( double )  rtp - > rxcore . tv_usec  /  1000000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* map timestamp to a real time */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > seedrxts  =  timestamp ;  /* Their RTP timestamp started with this */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-08 23:19:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtp - > rxcore . tv_sec  - =  timestamp  /  rate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > rxcore . tv_usec  - =  ( timestamp  %  rate )  *  125 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Round to 0.1ms for nice, pretty timestamps */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > rxcore . tv_usec  - =  rtp - > rxcore . tv_usec  %  100 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-19 23:47:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sanitize_tv ( & rtp - > rxcore ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									gettimeofday ( & now , NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* rxcore is the mapping between the RTP timestamp and _our_ real time from gettimeofday() */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-08 23:19:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tv - > tv_sec  =  rtp - > rxcore . tv_sec  +  timestamp  /  rate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tv - > tv_usec  =  rtp - > rxcore . tv_usec  +  ( timestamp  %  rate )  *  125 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-19 23:47:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									sanitize_tv ( tv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-08 23:19:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									prog  =  ( double ) ( ( timestamp - rtp - > seedrxts ) / ( float ) ( rate ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									dtv  =  ( double ) rtp - > drxcore  +  ( double ) ( prog ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									current_time  =  ( double ) now . tv_sec  +  ( double ) now . tv_usec / 1000000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									transit  =  current_time  -  dtv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									d  =  transit  -  rtp - > rxtransit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rxtransit  =  transit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( d < 0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										d = - d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rxjitter  + =  ( 1. / 16. )  *  ( d  -  rtp - > rxjitter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > rtcp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rtp - > rxjitter  >  rtp - > rtcp - > maxrxjitter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp - > maxrxjitter  =  rtp - > rxjitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rtp - > rtcp - > rxjitter_count  = =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp - > minrxjitter  =  rtp - > rxjitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rtp - > rtcp  & &  rtp - > rxjitter  <  rtp - > rtcp - > minrxjitter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp - > minrxjitter  =  rtp - > rxjitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										normdev_rxjitter_current  =  normdev_compute ( rtp - > rtcp - > normdev_rxjitter , rtp - > rxjitter , rtp - > rtcp - > rxjitter_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > rtcp - > stdev_rxjitter  =  stddev_compute ( rtp - > rtcp - > stdev_rxjitter , rtp - > rxjitter , rtp - > rtcp - > normdev_rxjitter , normdev_rxjitter_current , rtp - > rtcp - > rxjitter_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > rtcp - > normdev_rxjitter  =  normdev_rxjitter_current ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > rtcp - > rxjitter_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_frame  * send_dtmf ( struct  ast_rtp_instance  * instance ,  enum  ast_frame_type  type ,  int  compensate )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 18:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sockaddr_in  remote_address  =  {  0 ,  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rtp_instance_get_remote_address ( instance ,  & remote_address ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( ( compensate  & &  type  = =  AST_FRAME_DTMF_END )  | |  ( type  = =  AST_FRAME_DTMF_BEGIN ) )  & &  ast_tvcmp ( ast_tvnow ( ) ,  rtp - > dtmfmute )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Ignore potential DTMF echo from '%s' \n " ,  ast_inet_ntoa ( remote_address . sin_addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > resp  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > dtmfsamples  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Sending dtmf: %d (%c), at %s \n " ,  rtp - > resp ,  rtp - > resp ,  ast_inet_ntoa ( remote_address . sin_addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > resp  = =  ' X ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . frametype  =  AST_FRAME_CONTROL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtp - > f . subclass . integer  =  AST_CONTROL_FLASH ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . frametype  =  type ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtp - > f . subclass . integer  =  rtp - > resp ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . datalen  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . samples  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . mallocd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . src  =  " RTP " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & rtp - > f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_frame  * process_dtmf_rfc2833 ( struct  ast_rtp_instance  * instance ,  unsigned  char  * data ,  int  len ,  unsigned  int  seqno ,  unsigned  int  timestamp ,  struct  sockaddr_in  * sin ,  int  payloadtype ,  int  mark )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 18:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sockaddr_in  remote_address  =  {  0 ,  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									unsigned  int  event ,  event_end ,  samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  resp  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  * f  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rtp_instance_get_remote_address ( instance ,  & remote_address ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Figure out event, event end, and samples */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									event  =  ntohl ( * ( ( unsigned  int  * ) ( data ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									event  > > =  24 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									event_end  =  ntohl ( * ( ( unsigned  int  * ) ( data ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									event_end  < < =  8 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									event_end  > > =  24 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									samples  =  ntohl ( * ( ( unsigned  int  * ) ( data ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									samples  & =  0xFFFF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-06 23:11:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( rtp_debug_test_addr ( & remote_address ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( " Got  RTP RFC2833 from   %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u, mark %d, event %08x, end %d, duration %-5.5d)  \n " ,  ast_inet_ntoa ( remote_address . sin_addr ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    ntohs ( remote_address . sin_port ) ,  payloadtype ,  seqno ,  timestamp ,  len ,  ( mark ? 1 : 0 ) ,  event ,  ( ( event_end  &  0x80 ) ? 1 : 0 ) ,  samples ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Print out debug if turned on */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtpdebug  | |  option_debug  >  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 0 ,  " - RTP 2833 Event: %08x (len = %d) \n " ,  event ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Figure out what digit was pressed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( event  <  10 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resp  =  ' 0 '  +  event ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( event  <  11 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resp  =  ' * ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( event  <  12 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resp  =  ' # ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( event  <  16 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resp  =  ' A '  +  ( event  -  12 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( event  <  17 )  {         /* Event 16: Hook flash */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resp  =  ' X ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Not a supported event */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_DEBUG ,  " Ignoring RTP 2833 Event: %08x. Not a DTMF Digit. \n " ,  event ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_rtp_instance_get_prop ( instance ,  AST_RTP_PROPERTY_DTMF_COMPENSATE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( rtp - > lastevent  ! =  timestamp )  | |  ( rtp - > resp  & &  rtp - > resp  ! =  resp ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > resp  =  resp ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-13 13:39:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rtp - > dtmf_timeout  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											f  =  send_dtmf ( instance ,  AST_FRAME_DTMF_END ,  ast_rtp_instance_get_prop ( instance ,  AST_RTP_PROPERTY_DTMF_COMPENSATE ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f - > len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > lastevent  =  timestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-13 13:39:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/*  The duration parameter measures the complete
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    duration  of  the  event  ( from  the  beginning )  -  RFC2833 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    Account  for  the  fact  that  duration  is  only  16  bits  long 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ( about  8  seconds  at  8000  Hz )  and  can  wrap  is  digit 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    is  hold  for  too  long .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unsigned  int  new_duration  =  rtp - > dtmf_duration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unsigned  int  last_duration  =  new_duration  &  0xFFFF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( last_duration  >  64000  & &  samples  <  last_duration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											new_duration  + =  0xFFFF  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_duration  =  ( new_duration  &  ~ 0xFFFF )  |  samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( event_end  &  0x80 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* End event */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( rtp - > lastevent  ! =  seqno )  & &  rtp - > resp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > dtmf_duration  =  new_duration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												f  =  send_dtmf ( instance ,  AST_FRAME_DTMF_END ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												f - > len  =  ast_tvdiff_ms ( ast_samp2tv ( rtp - > dtmf_duration ,  rtp_get_rate ( f - > subclass . codec ) ) ,  ast_tv ( 0 ,  0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-13 13:39:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												rtp - > resp  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > dtmf_duration  =  rtp - > dtmf_timeout  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Begin/continuation */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtp - > resp  & &  rtp - > resp  ! =  resp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Another digit already began. End it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												f  =  send_dtmf ( instance ,  AST_FRAME_DTMF_END ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												f - > len  =  ast_tvdiff_ms ( ast_samp2tv ( rtp - > dtmf_duration ,  rtp_get_rate ( f - > subclass . codec ) ) ,  ast_tv ( 0 ,  0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-13 13:39:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												rtp - > resp  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > dtmf_duration  =  rtp - > dtmf_timeout  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtp - > resp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Digit continues */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > dtmf_duration  =  new_duration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* New digit began */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > resp  =  resp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												f  =  send_dtmf ( instance ,  AST_FRAME_DTMF_BEGIN ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > dtmf_duration  =  samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > dtmf_timeout  =  timestamp  +  rtp - > dtmf_duration  +  dtmftimeout ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-13 13:39:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > lastevent  =  seqno ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > dtmfsamples  =  samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_frame  * process_dtmf_cisco ( struct  ast_rtp_instance  * instance ,  unsigned  char  * data ,  int  len ,  unsigned  int  seqno ,  unsigned  int  timestamp ,  struct  sockaddr_in  * sin ,  int  payloadtype ,  int  mark )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  event ,  flags ,  power ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  resp  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  seq ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  * f  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( len  <  4 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*      The format of Cisco RTP DTMF packet looks like next:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+ 0                               -  sequence  number  of  DTMF  RTP  packet  ( begins  from  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														  wrapped  to  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+ 1                               -  set  of  flags 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+ 1  ( bit  0 )               -  flaps  by  different  DTMF  digits  delimited  by  audio 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														  or  repeated  digit  without  audio ? ? ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+ 2  ( + 4 , + 6 , . . . )   -  power  level ?  ( rises  from  0  to  32  at  begin  of  tone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														  then  falls  to  0  at  its  end ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										+ 3  ( + 5 , + 7 , . . . )   -  detected  DTMF  digit  ( 0. .9 , * , # , A - D , . . . ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Repeated  DTMF  information  ( bytes  4 / 5 ,  6 / 7 )  is  history  shifted  right 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										by  each  new  packet  and  thus  provides  some  redudancy . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Sample  of  Cisco  RTP  DTMF  packet  is  ( all  data  in  hex ) : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											19  07  00  02  12  02  20  02 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										showing  end  of  DTMF  digit  ' 2 ' . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										The  packets 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											27  07  00  02  0 A  02  20  02 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											28  06  20  02  00  02  0 A  02 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										shows  begin  of  new  digit  ' 2 '  with  very  short  pause  ( 20  ms )  after 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										previous  digit  ' 2 ' .  Bit  + 1.0  flips  at  begin  of  new  digit . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Cisco  RTP  DTMF  packets  comes  as  replacement  of  audio  RTP  packets 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										so  its  uses  the  same  sequencing  and  timestamping  rules  as  replaced 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										audio  packets .  Repeat  interval  of  DTMF  packets  is  20  ms  and  not  rely 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										on  audio  framing  parameters .  Marker  bit  isn ' t  used  within  stream  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										DTMFs  nor  audio  stream  coming  immediately  after  DTMF  stream .  Timestamps 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										are  not  sequential  at  borders  between  DTMF  and  audio  streams , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									seq  =  data [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									flags  =  data [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									power  =  data [ 2 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									event  =  data [ 3 ]  &  0x1f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( option_debug  >  2  | |  rtpdebug ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 0 ,  " Cisco DTMF Digit: %02x (len=%d, seq=%d, flags=%02x, power=%d, history count=%d) \n " ,  event ,  len ,  seq ,  flags ,  power ,  ( len  -  4 )  /  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( event  <  10 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resp  =  ' 0 '  +  event ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( event  <  11 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resp  =  ' * ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( event  <  12 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resp  =  ' # ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( event  <  16 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resp  =  ' A '  +  ( event  -  12 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( event  <  17 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										resp  =  ' X ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( ! rtp - > resp  & &  power )  | |  ( rtp - > resp  & &  ( rtp - > resp  ! =  resp ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > resp  =  resp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Why we should care on DTMF compensation at reception? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_rtp_instance_get_prop ( instance ,  AST_RTP_PROPERTY_DTMF_COMPENSATE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f  =  send_dtmf ( instance ,  AST_FRAME_DTMF_BEGIN ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > dtmfsamples  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ( rtp - > resp  = =  resp )  & &  ! power )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										f  =  send_dtmf ( instance ,  AST_FRAME_DTMF_END ,  ast_rtp_instance_get_prop ( instance ,  AST_RTP_PROPERTY_DTMF_COMPENSATE ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										f - > samples  =  rtp - > dtmfsamples  *  ( rtp_get_rate ( f - > subclass . codec )  /  1000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										rtp - > resp  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( rtp - > resp  = =  resp ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtp - > dtmfsamples  + =  20  *  ( rtp_get_rate ( f - > subclass . codec )  /  1000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-13 13:39:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtp - > dtmf_timeout  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_frame  * process_cn_rfc3389 ( struct  ast_rtp_instance  * instance ,  unsigned  char  * data ,  int  len ,  unsigned  int  seqno ,  unsigned  int  timestamp ,  struct  sockaddr_in  * sin ,  int  payloadtype ,  int  mark )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Convert comfort noise into audio with various codecs.  Unfortunately this doesn't
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   totally  help  us  out  becuase  we  don ' t  have  an  engine  to  keep  it  going  and  we  are  not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   guaranteed  to  have  it  every  20 ms  or  anything  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtpdebug ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 0 ,  " - RTP 3389 Comfort noise event: Level %d (len = %d) \n " ,  rtp - > lastrxformat ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_test_flag ( rtp ,  FLAG_3389_WARNING ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 18:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  sockaddr_in  remote_address  =  {  0 ,  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_rtp_instance_get_remote_address ( instance ,  & remote_address ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_NOTICE ,  " Comfort noise support incomplete in Asterisk (RFC 3389). Please turn off on client if possible. Client IP: %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_inet_ntoa ( remote_address . sin_addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_set_flag ( rtp ,  FLAG_3389_WARNING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Must have at least one byte */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! len ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( len  <  24 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . data . ptr  =  rtp - > rawdata  +  AST_FRIENDLY_OFFSET ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . datalen  =  len  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . offset  =  AST_FRIENDLY_OFFSET ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memcpy ( rtp - > f . data . ptr ,  data  +  1 ,  len  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . data . ptr  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . datalen  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . frametype  =  AST_FRAME_CNG ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtp - > f . subclass . integer  =  data [ 0 ]  &  0x7f ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									rtp - > f . datalen  =  len  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . samples  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . delivery . tv_usec  =  rtp - > f . delivery . tv_sec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & rtp - > f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_frame  * ast_rtcp_read ( struct  ast_rtp_instance  * instance )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sockaddr_in  sin ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									socklen_t  len  =  sizeof ( sin ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  rtcpdata [ 8192  +  AST_FRIENDLY_OFFSET ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  * rtcpheader  =  ( unsigned  int  * ) ( rtcpdata  +  AST_FRIENDLY_OFFSET ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ,  packetwords ,  position  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  * f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Read in RTCP data from the socket */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( res  =  recvfrom ( rtp - > rtcp - > s ,  rtcpdata  +  AST_FRIENDLY_OFFSET ,  sizeof ( rtcpdata )  -  sizeof ( unsigned  int )  *  AST_FRIENDLY_OFFSET ,  0 ,  ( struct  sockaddr  * ) & sin ,  & len ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_assert ( errno  ! =  EBADF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( errno  ! =  EAGAIN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " RTCP Read error: %s.  Hanging up. \n " ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									packetwords  =  res  /  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_rtp_instance_get_prop ( instance ,  AST_RTP_PROPERTY_NAT ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Send to whoever sent to us */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( rtp - > rtcp - > them . sin_addr . s_addr  ! =  sin . sin_addr . s_addr )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ( rtp - > rtcp - > them . sin_port  ! =  sin . sin_port ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memcpy ( & rtp - > rtcp - > them ,  & sin ,  sizeof ( rtp - > rtcp - > them ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( option_debug  | |  rtpdebug ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 0 ,  " RTCP NAT: Got RTCP from other end. Now sending to address %s:%d \n " ,  ast_inet_ntoa ( rtp - > rtcp - > them . sin_addr ) ,  ntohs ( rtp - > rtcp - > them . sin_port ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Got RTCP report of %d bytes \n " ,  res ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( position  <  packetwords )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  i ,  pt ,  rc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unsigned  int  length ,  dlsr ,  lsr ,  msw ,  lsw ,  comp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  timeval  now ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										double  rttsec ,  reported_jitter ,  reported_normdev_jitter_current ,  normdevrtt_current ,  reported_lost ,  reported_normdev_lost_current ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										uint64_t  rtt  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										i  =  position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										length  =  ntohl ( rtcpheader [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pt  =  ( length  &  0xff0000 )  > >  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rc  =  ( length  &  0x1f000000 )  > >  24 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										length  & =  0xffff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( i  +  length )  >  packetwords )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( option_debug  | |  rtpdebug ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_DEBUG ,  " RTCP Read too short \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rtcp_debug_test_addr ( & sin ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verbose ( " \n \n Got RTCP from %s:%d \n " ,  ast_inet_ntoa ( sin . sin_addr ) ,  ntohs ( sin . sin_port ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verbose ( " PT: %d(%s) \n " ,  pt ,  ( pt  = =  200 )  ?  " Sender Report "  :  ( pt  = =  201 )  ?  " Receiver Report "  :  ( pt  = =  192 )  ?  " H.261 FUR "  :  " Unknown " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verbose ( " Reception reports: %d \n " ,  rc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verbose ( " SSRC of sender: %u \n " ,  rtcpheader [ i  +  1 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										i  + =  2 ;  /* Advance past header and ssrc */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( pt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  RTCP_PT_SR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											gettimeofday ( & rtp - > rtcp - > rxlsr , NULL ) ;  /* To be able to populate the dlsr */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp - > spc  =  ntohl ( rtcpheader [ i + 3 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp - > soc  =  ntohl ( rtcpheader [ i  +  4 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp - > themrxlsr  =  ( ( ntohl ( rtcpheader [ i ] )  &  0x0000ffff )  < <  16 )  |  ( ( ntohl ( rtcpheader [ i  +  1 ] )  &  0xffff0000 )  > >  16 ) ;  /* Going to LSR in RR*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtcp_debug_test_addr ( & sin ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verbose ( " NTP timestamp: %lu.%010lu \n " ,  ( unsigned  long )  ntohl ( rtcpheader [ i ] ) ,  ( unsigned  long )  ntohl ( rtcpheader [ i  +  1 ] )  *  4096 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verbose ( " RTP timestamp: %lu \n " ,  ( unsigned  long )  ntohl ( rtcpheader [ i  +  2 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verbose ( " SPC: %lu \t SOC: %lu \n " ,  ( unsigned  long )  ntohl ( rtcpheader [ i  +  3 ] ) ,  ( unsigned  long )  ntohl ( rtcpheader [ i  +  4 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											i  + =  5 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rc  <  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Intentional fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  RTCP_PT_RR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Don't handle multiple reception reports (rc > 1) yet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Calculate RTT per RFC */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											gettimeofday ( & now ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											timeval2ntp ( now ,  & msw ,  & lsw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ntohl ( rtcpheader [ i  +  4 ] )  & &  ntohl ( rtcpheader [ i  +  5 ] ) )  {  /* We must have the LSR && DLSR */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												comp  =  ( ( msw  &  0xffff )  < <  16 )  |  ( ( lsw  &  0xffff0000 )  > >  16 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												lsr  =  ntohl ( rtcpheader [ i  +  4 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												dlsr  =  ntohl ( rtcpheader [ i  +  5 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtt  =  comp  -  lsr  -  dlsr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Convert end to end delay to usec (keeping the calculation in 64bit space)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   sess - > ee_delay  =  ( eedelay  *  1000 )  /  65536 ;  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( rtt  <  4294 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													rtt  =  ( rtt  *  1000000 )  > >  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													rtt  =  ( rtt  *  1000 )  > >  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													rtt  * =  1000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtt  =  rtt  /  1000. ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rttsec  =  rtt  /  1000. ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > rtcp - > rtt  =  rttsec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( comp  -  dlsr  > =  lsr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													rtp - > rtcp - > accumulated_transit  + =  rttsec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( rtp - > rtcp - > rtt_count  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														rtp - > rtcp - > minrtt  =  rttsec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( rtp - > rtcp - > maxrtt < rttsec ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														rtp - > rtcp - > maxrtt  =  rttsec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( rtp - > rtcp - > minrtt > rttsec ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														rtp - > rtcp - > minrtt  =  rttsec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													normdevrtt_current  =  normdev_compute ( rtp - > rtcp - > normdevrtt ,  rttsec ,  rtp - > rtcp - > rtt_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													rtp - > rtcp - > stdevrtt  =  stddev_compute ( rtp - > rtcp - > stdevrtt ,  rttsec ,  rtp - > rtcp - > normdevrtt ,  normdevrtt_current ,  rtp - > rtcp - > rtt_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													rtp - > rtcp - > normdevrtt  =  normdevrtt_current ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													rtp - > rtcp - > rtt_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( rtcp_debug_test_addr ( & sin ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_verbose ( " Internal RTCP NTP clock skew detected:  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															   " lsr=%u, now=%u, dlsr=%u (%d:%03dms),  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														    " diff=%d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														    lsr ,  comp ,  dlsr ,  dlsr  /  65536 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														    ( dlsr  %  65536 )  *  1000  /  65536 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														    dlsr  -  ( comp  -  lsr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp - > reported_jitter  =  ntohl ( rtcpheader [ i  +  3 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reported_jitter  =  ( double )  rtp - > rtcp - > reported_jitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtp - > rtcp - > reported_jitter_count  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > rtcp - > reported_minjitter  =  reported_jitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( reported_jitter  <  rtp - > rtcp - > reported_minjitter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > rtcp - > reported_minjitter  =  reported_jitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( reported_jitter  >  rtp - > rtcp - > reported_maxjitter ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > rtcp - > reported_maxjitter  =  reported_jitter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reported_normdev_jitter_current  =  normdev_compute ( rtp - > rtcp - > reported_normdev_jitter ,  reported_jitter ,  rtp - > rtcp - > reported_jitter_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp - > reported_stdev_jitter  =  stddev_compute ( rtp - > rtcp - > reported_stdev_jitter ,  reported_jitter ,  rtp - > rtcp - > reported_normdev_jitter ,  reported_normdev_jitter_current ,  rtp - > rtcp - > reported_jitter_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp - > reported_normdev_jitter  =  reported_normdev_jitter_current ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp - > reported_lost  =  ntohl ( rtcpheader [ i  +  1 ] )  &  0xffffff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reported_lost  =  ( double )  rtp - > rtcp - > reported_lost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* using same counter as for jitter */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtp - > rtcp - > reported_jitter_count  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > rtcp - > reported_minlost  =  reported_lost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( reported_lost  <  rtp - > rtcp - > reported_minlost ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > rtcp - > reported_minlost  =  reported_lost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( reported_lost  >  rtp - > rtcp - > reported_maxlost ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > rtcp - > reported_maxlost  =  reported_lost ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											reported_normdev_lost_current  =  normdev_compute ( rtp - > rtcp - > reported_normdev_lost ,  reported_lost ,  rtp - > rtcp - > reported_jitter_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp - > reported_stdev_lost  =  stddev_compute ( rtp - > rtcp - > reported_stdev_lost ,  reported_lost ,  rtp - > rtcp - > reported_normdev_lost ,  reported_normdev_lost_current ,  rtp - > rtcp - > reported_jitter_count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp - > reported_normdev_lost  =  reported_normdev_lost_current ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp - > reported_jitter_count + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtcp_debug_test_addr ( & sin ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verbose ( "   Fraction lost: %ld \n " ,  ( ( ( long )  ntohl ( rtcpheader [ i  +  1 ] )  &  0xff000000 )  > >  24 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verbose ( "   Packets lost so far: %d \n " ,  rtp - > rtcp - > reported_lost ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verbose ( "   Highest sequence number: %ld \n " ,  ( long )  ( ntohl ( rtcpheader [ i  +  2 ] )  &  0xffff ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verbose ( "   Sequence number cycles: %ld \n " ,  ( long )  ( ntohl ( rtcpheader [ i  +  2 ] )  &  0xffff )  > >  16 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verbose ( "   Interarrival jitter: %u \n " ,  rtp - > rtcp - > reported_jitter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verbose ( "   Last SR(our NTP): %lu.%010lu \n " , ( unsigned  long )  ntohl ( rtcpheader [ i  +  4 ] )  > >  16 , ( ( unsigned  long )  ntohl ( rtcpheader [ i  +  4 ] )  < <  16 )  *  4096 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verbose ( "   DLSR: %4.4f (sec) \n " , ntohl ( rtcpheader [ i  +  5 ] ) / 65536.0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( rtt ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_verbose ( "   RTT: %lu(sec) \n " ,  ( unsigned  long )  rtt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												manager_event ( EVENT_FLAG_REPORTING ,  " RTCPReceived " ,  " From %s:%d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " PT: %d(%s) \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " ReceptionReports: %d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " SenderSSRC: %u \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " FractionLost: %ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " PacketsLost: %d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " HighestSequence: %ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " SequenceNumberCycles: %ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " IAJitter: %u \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " LastSR: %lu.%010lu \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " DLSR: %4.4f(sec) \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      " RTT: %llu(sec) \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ast_inet_ntoa ( sin . sin_addr ) ,  ntohs ( sin . sin_port ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      pt ,  ( pt  = =  200 )  ?  " Sender Report "  :  ( pt  = =  201 )  ?  " Receiver Report "  :  ( pt  = =  192 )  ?  " H.261 FUR "  :  " Unknown " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      rc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      rtcpheader [ i  +  1 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ( ( ( long )  ntohl ( rtcpheader [ i  +  1 ] )  &  0xff000000 )  > >  24 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      rtp - > rtcp - > reported_lost , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ( long )  ( ntohl ( rtcpheader [ i  +  2 ] )  &  0xffff ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ( long )  ( ntohl ( rtcpheader [ i  +  2 ] )  &  0xffff )  > >  16 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      rtp - > rtcp - > reported_jitter , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ( unsigned  long )  ntohl ( rtcpheader [ i  +  4 ] )  > >  16 ,  ( ( unsigned  long )  ntohl ( rtcpheader [ i  +  4 ] )  < <  16 )  *  4096 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ntohl ( rtcpheader [ i  +  5 ] ) / 65536.0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ( unsigned  long  long ) rtt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												manager_event ( EVENT_FLAG_REPORTING ,  " RTCPReceived " ,  " From %s:%d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " PT: %d(%s) \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " ReceptionReports: %d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " SenderSSRC: %u \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " FractionLost: %ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " PacketsLost: %d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " HighestSequence: %ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " SequenceNumberCycles: %ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " IAJitter: %u \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																    " LastSR: %lu.%010lu \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      " DLSR: %4.4f(sec) \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ast_inet_ntoa ( sin . sin_addr ) ,  ntohs ( sin . sin_port ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      pt ,  ( pt  = =  200 )  ?  " Sender Report "  :  ( pt  = =  201 )  ?  " Receiver Report "  :  ( pt  = =  192 )  ?  " H.261 FUR "  :  " Unknown " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      rc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      rtcpheader [ i  +  1 ] , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ( ( ( long )  ntohl ( rtcpheader [ i  +  1 ] )  &  0xff000000 )  > >  24 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      rtp - > rtcp - > reported_lost , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ( long )  ( ntohl ( rtcpheader [ i  +  2 ] )  &  0xffff ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ( long )  ( ntohl ( rtcpheader [ i  +  2 ] )  &  0xffff )  > >  16 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      rtp - > rtcp - > reported_jitter , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ( unsigned  long )  ntohl ( rtcpheader [ i  +  4 ] )  > >  16 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ( ( unsigned  long )  ntohl ( rtcpheader [ i  +  4 ] )  < <  16 )  *  4096 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													      ntohl ( rtcpheader [ i  +  5 ] ) / 65536.0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  RTCP_PT_FUR : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtcp_debug_test_addr ( & sin ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verbose ( " Received an RTCP Fast Update Request \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > f . frametype  =  AST_FRAME_CONTROL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rtp - > f . subclass . integer  =  AST_CONTROL_VIDUPDATE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											rtp - > f . datalen  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > f . samples  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > f . mallocd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > f . src  =  " RTP " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f  =  & rtp - > f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  RTCP_PT_SDES : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtcp_debug_test_addr ( & sin ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verbose ( " Received an SDES from %s:%d \n " ,  ast_inet_ntoa ( rtp - > rtcp - > them . sin_addr ) ,  ntohs ( rtp - > rtcp - > them . sin_port ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  RTCP_PT_BYE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtcp_debug_test_addr ( & sin ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verbose ( " Received a BYE from %s:%d \n " ,  ast_inet_ntoa ( rtp - > rtcp - > them . sin_addr ) ,  ntohs ( rtp - > rtcp - > them . sin_port ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Unknown RTCP packet (pt=%d) received from %s:%d \n " ,  pt ,  ast_inet_ntoa ( rtp - > rtcp - > them . sin_addr ) ,  ntohs ( rtp - > rtcp - > them . sin_port ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										position  + =  ( length  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rtcp - > rtcp_info  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  bridge_p2p_rtp_write ( struct  ast_rtp_instance  * instance ,  unsigned  int  * rtpheader ,  int  len ,  int  hdrlen )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp_instance  * instance1  =  ast_rtp_instance_get_bridged ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ,  * bridged  =  ast_rtp_instance_get_data ( instance1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ,  payload  =  0 ,  bridged_payload  =  0 ,  mark ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp_payload_type  payload_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  reconstruct  =  ntohl ( rtpheader [ 0 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 18:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sockaddr_in  remote_address  =  {  0 ,  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Get fields from packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									payload  =  ( reconstruct  &  0x7f0000 )  > >  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mark  =  ( ( ( reconstruct  &  0x800000 )  > >  23 )  ! =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Check what the payload value should be */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									payload_type  =  ast_rtp_codecs_payload_lookup ( ast_rtp_instance_get_codecs ( instance ) ,  payload ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Otherwise adjust bridged payload to match */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									bridged_payload  =  ast_rtp_codecs_payload_code ( ast_rtp_instance_get_codecs ( instance1 ) ,  payload_type . asterisk_format ,  payload_type . code ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If the payload coming in is not one of the negotiated ones then send it to the core, this will cause formats to change and the bridge to break */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( ast_rtp_instance_get_codecs ( instance1 ) - > payloads [ bridged_payload ] . code ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If the marker bit has been explicitly set turn it on */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_test_flag ( rtp ,  FLAG_NEED_MARKER_BIT ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mark  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_clear_flag ( rtp ,  FLAG_NEED_MARKER_BIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Reconstruct part of the packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reconstruct  & =  0xFF80FFFF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reconstruct  | =  ( bridged_payload  < <  16 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									reconstruct  | =  ( mark  < <  23 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpheader [ 0 ]  =  htonl ( reconstruct ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rtp_instance_get_remote_address ( instance1 ,  & remote_address ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Send the packet back out */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  sendto ( bridged - > s ,  ( void  * ) rtpheader ,  len ,  0 ,  ( struct  sockaddr  * ) & remote_address ,  sizeof ( remote_address ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ast_rtp_instance_get_prop ( instance1 ,  AST_RTP_PROPERTY_NAT )  | |  ( ast_rtp_instance_get_prop ( instance1 ,  AST_RTP_PROPERTY_NAT )  & &  ( ast_test_flag ( bridged ,  FLAG_NAT_ACTIVE )  = =  FLAG_NAT_ACTIVE ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " RTP Transmission error of packet to %s:%d: %s \n " ,  ast_inet_ntoa ( remote_address . sin_addr ) ,  ntohs ( remote_address . sin_port ) ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ( ( ast_test_flag ( bridged ,  FLAG_NAT_ACTIVE )  = =  FLAG_NAT_INACTIVE )  | |  rtpdebug )  & &  ! ast_test_flag ( bridged ,  FLAG_NAT_INACTIVE_NOWARN ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( option_debug  | |  rtpdebug ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 0 ,  " RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio... \n " ,  ast_inet_ntoa ( remote_address . sin_addr ) ,  ntohs ( remote_address . sin_port ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_set_flag ( bridged ,  FLAG_NAT_INACTIVE_NOWARN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( rtp_debug_test_addr ( & remote_address ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( " Sent RTP P2P packet to %s:%u (type %-2.2d, len %-6.6u) \n " ,  ast_inet_ntoa ( remote_address . sin_addr ) ,  ntohs ( remote_address . sin_port ) ,  bridged_payload ,  len  -  hdrlen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_frame  * ast_rtp_read ( struct  ast_rtp_instance  * instance ,  int  rtcp )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sockaddr_in  sin ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									socklen_t  len  =  sizeof ( sin ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ,  hdrlen  =  12 ,  version ,  payloadtype ,  padding ,  mark ,  ext ,  cc ,  prev_seqno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  * rtpheader  =  ( unsigned  int * ) ( rtp - > rawdata  +  AST_FRIENDLY_OFFSET ) ,  seqno ,  ssrc ,  timestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp_payload_type  payload ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 18:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sockaddr_in  remote_address  =  {  0 ,  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If this is actually RTCP let's hop on over and handle it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtcp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rtp - > rtcp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  ast_rtcp_read ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If we are currently sending DTMF to the remote party send a continuation packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > sending_digit )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_rtp_dtmf_continuation ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Actually read in the data from the socket */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( res  =  recvfrom ( rtp - > s ,  rtp - > rawdata  +  AST_FRIENDLY_OFFSET ,  sizeof ( rtp - > rawdata )  -  AST_FRIENDLY_OFFSET ,  0 ,  ( struct  sockaddr * ) & sin ,  & len ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_assert ( errno  ! =  EBADF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( errno  ! =  EAGAIN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " RTP Read error: %s. Hanging up. \n " ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Make sure the data that was read in is actually enough to make up an RTP packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  <  hdrlen )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " RTP Read too short \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If strict RTP protection is enabled see if we need to learn the remote address or if we need to drop the packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > strict_rtp_state  = =  STRICT_RTP_LEARN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memcpy ( & rtp - > strict_rtp_address ,  & sin ,  sizeof ( rtp - > strict_rtp_address ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > strict_rtp_state  =  STRICT_RTP_CLOSED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( rtp - > strict_rtp_state  = =  STRICT_RTP_CLOSED )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( rtp - > strict_rtp_address . sin_addr . s_addr  ! =  sin . sin_addr . s_addr )  | |  ( rtp - > strict_rtp_address . sin_port  ! =  sin . sin_port ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-18 15:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Hmm, not the strict addres. Perhaps we're getting audio from the alternate? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( rtp - > alt_rtp_address . sin_addr . s_addr  = =  sin . sin_addr . s_addr )  & &  ( rtp - > alt_rtp_address . sin_port  = =  sin . sin_port ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* ooh, we did! You're now the new expected address, son! */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > strict_rtp_address  =  sin ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else   { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Received RTP packet from %s:%d, dropping due to strict RTP protection. Expected it to be from %s:%d \n " ,  ast_inet_ntoa ( sin . sin_addr ) ,  ntohs ( sin . sin_port ) ,  ast_inet_ntoa ( rtp - > strict_rtp_address . sin_addr ) ,  ntohs ( rtp - > strict_rtp_address . sin_port ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Get fields and verify this is an RTP packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									seqno  =  ntohl ( rtpheader [ 0 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rtp_instance_get_remote_address ( instance ,  & remote_address ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( version  =  ( seqno  &  0xC0000000 )  > >  30 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( ast_stun_handle_packet ( rtp - > s ,  & sin ,  rtp - > rawdata  +  AST_FRIENDLY_OFFSET ,  res ,  NULL ,  NULL )  = =  AST_STUN_ACCEPT )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ( ! remote_address . sin_port  & &  ! remote_address . sin_addr . s_addr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_rtp_instance_set_remote_address ( instance ,  & sin ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If symmetric RTP is enabled see if the remote side is not what we expected and change where we are sending audio */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_rtp_instance_get_prop ( instance ,  AST_RTP_PROPERTY_NAT ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( remote_address . sin_addr . s_addr  ! =  sin . sin_addr . s_addr )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    ( remote_address . sin_port  ! =  sin . sin_port ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_rtp_instance_set_remote_address ( instance ,  & sin ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memcpy ( & remote_address ,  & sin ,  sizeof ( remote_address ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtp - > rtcp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												memcpy ( & rtp - > rtcp - > them ,  & sin ,  sizeof ( rtp - > rtcp - > them ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtp - > rtcp - > them . sin_port  =  htons ( ntohs ( sin . sin_port ) + 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rxseqno  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_set_flag ( rtp ,  FLAG_NAT_ACTIVE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( option_debug  | |  rtpdebug ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 0 ,  " RTP NAT: Got audio from other end. Now sending to address %s:%d \n " ,  ast_inet_ntoa ( remote_address . sin_addr ) ,  ntohs ( remote_address . sin_port ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If we are directly bridged to another instance send the audio directly out */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_rtp_instance_get_bridged ( instance )  & &  ! bridge_p2p_rtp_write ( instance ,  rtpheader ,  res ,  hdrlen ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If the version is not what we expected by this point then just drop the packet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( version  ! =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Pull out the various other fields we will need */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									payloadtype  =  ( seqno  &  0x7f0000 )  > >  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									padding  =  seqno  &  ( 1  < <  29 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mark  =  seqno  &  ( 1  < <  23 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ext  =  seqno  &  ( 1  < <  28 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cc  =  ( seqno  &  0xF000000 )  > >  24 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									seqno  & =  0xffff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									timestamp  =  ntohl ( rtpheader [ 1 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ssrc  =  ntohl ( rtpheader [ 2 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Force a marker bit if the SSRC changes */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! mark  & &  rtp - > rxssrc  & &  rtp - > rxssrc  ! =  ssrc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( option_debug  | |  rtpdebug )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Forcing Marker bit, because SSRC has changed \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mark  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Remove any padding bytes that may be present */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( padding )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  - =  rtp - > rawdata [ AST_FRIENDLY_OFFSET  +  res  -  1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Skip over any CSRC fields */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( cc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hdrlen  + =  cc  *  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Look for any RTP extensions, currently we do not support any */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ext )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hdrlen  + =  ( ntohl ( rtpheader [ hdrlen / 4 ] )  &  0xffff )  < <  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										hdrlen  + =  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( option_debug )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  profile ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											profile  =  ( ntohl ( rtpheader [ 3 ] )  &  0xffff0000 )  > >  16 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( profile  = =  0x505a ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Found Zfone extension in RTP stream - zrtp - not supported. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Found unknown RTP Extensions %x \n " ,  profile ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Make sure after we potentially mucked with the header length that it is once again valid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  <  hdrlen )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " RTP Read too short (%d, expecting %d \n " ,  res ,  hdrlen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rxcount + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > rxcount  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > seedrxseqno  =  seqno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Do not schedule RR if RTCP isn't run */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > rtcp  & &  rtp - > rtcp - > them . sin_addr . s_addr  & &  rtp - > rtcp - > schedid  <  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Schedule transmission of Receiver Report */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > rtcp - > schedid  =  ast_sched_add ( rtp - > sched ,  ast_rtcp_calc_interval ( rtp ) ,  ast_rtcp_write ,  rtp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( int ) rtp - > lastrxseqno  -  ( int ) seqno   >  100 )  /* if so it would indicate that the sender cycled; allow for misordering */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > cycles  + =  RTP_SEQ_MOD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									prev_seqno  =  rtp - > lastrxseqno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > lastrxseqno  =  seqno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! rtp - > themssrc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > themssrc  =  ntohl ( rtpheader [ 2 ] ) ;  /* Record their SSRC to put in future RR */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp_debug_test_addr ( & sin ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verbose ( " Got  RTP packet from    %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    ast_inet_ntoa ( sin . sin_addr ) ,  ntohs ( sin . sin_port ) ,  payloadtype ,  seqno ,  timestamp , res  -  hdrlen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									payload  =  ast_rtp_codecs_payload_lookup ( ast_rtp_instance_get_codecs ( instance ) ,  payloadtype ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If the payload is not actually an Asterisk one but a special one pass it off to the respective handler */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! payload . asterisk_format )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_frame  * f  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( payload . code  = =  AST_RTP_DTMF )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f  =  process_dtmf_rfc2833 ( instance ,  rtp - > rawdata  +  AST_FRIENDLY_OFFSET  +  hdrlen ,  res  -  hdrlen ,  seqno ,  timestamp ,  & sin ,  payloadtype ,  mark ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( payload . code  = =  AST_RTP_CISCO_DTMF )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f  =  process_dtmf_cisco ( instance ,  rtp - > rawdata  +  AST_FRIENDLY_OFFSET  +  hdrlen ,  res  -  hdrlen ,  seqno ,  timestamp ,  & sin ,  payloadtype ,  mark ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( payload . code  = =  AST_RTP_CN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f  =  process_cn_rfc3389 ( instance ,  rtp - > rawdata  +  AST_FRIENDLY_OFFSET  +  hdrlen ,  res  -  hdrlen ,  seqno ,  timestamp ,  & sin ,  payloadtype ,  mark ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_NOTICE ,  " Unknown RTP codec %d received from '%s' \n " ,  payloadtype ,  ast_inet_ntoa ( remote_address . sin_addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  f  ?  f  :  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtp - > lastrxformat  =  rtp - > f . subclass . codec  =  payload . code ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . frametype  =  ( rtp - > f . subclass . codec  &  AST_FORMAT_AUDIO_MASK )  ?  AST_FRAME_VOICE  :  ( rtp - > f . subclass . codec  &  AST_FORMAT_VIDEO_MASK )  ?  AST_FRAME_VIDEO  :  AST_FRAME_TEXT ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rxseqno  =  seqno ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-13 13:39:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > dtmf_timeout  & &  rtp - > dtmf_timeout  <  timestamp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > dtmf_timeout  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rtp - > resp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  ast_frame  * f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f  =  send_dtmf ( instance ,  AST_FRAME_DTMF_END ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											f - > len  =  ast_tvdiff_ms ( ast_samp2tv ( rtp - > dtmf_duration ,  rtp_get_rate ( f - > subclass . codec ) ) ,  ast_tv ( 0 ,  0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-13 13:39:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rtp - > resp  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > dtmf_timeout  =  rtp - > dtmf_duration  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									rtp - > lastrxts  =  timestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . src  =  " RTP " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . mallocd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . datalen  =  res  -  hdrlen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . data . ptr  =  rtp - > rawdata  +  hdrlen  +  AST_FRIENDLY_OFFSET ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . offset  =  hdrlen  +  AST_FRIENDLY_OFFSET ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > f . seqno  =  seqno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( rtp - > f . subclass . codec  = =  AST_FORMAT_T140  & &  ( int ) seqno  -  ( prev_seqno + 1 )  >  0  & &  ( int ) seqno  -  ( prev_seqno + 1 )  <  10 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										unsigned  char  * data  =  rtp - > f . data . ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memmove ( rtp - > f . data . ptr + 3 ,  rtp - > f . data . ptr ,  rtp - > f . datalen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . datalen  + = 3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* data + +  =  0xEF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* data + +  =  0xBF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* data  =  0xBD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( rtp - > f . subclass . codec  = =  AST_FORMAT_T140RED )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										unsigned  char  * data  =  rtp - > f . data . ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										unsigned  char  * header_end ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  num_generations ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  header_length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  diff  = ( int ) seqno  -  ( prev_seqno + 1 ) ;  /* if diff = 0, no drop*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtp - > f . subclass . codec  =  AST_FORMAT_T140 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										header_end  =  memchr ( data ,  ( ( * data )  &  0x7f ) ,  rtp - > f . datalen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-27 20:54:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( header_end  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										header_end + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										header_length  =  header_end  -  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										num_generations  =  header_length  /  4 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										len  =  header_length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! diff )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( x  =  0 ;  x  <  num_generations ;  x + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												len  + =  data [ x  *  4  +  3 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ( rtp - > f . datalen  -  len ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > f . data . ptr  + =  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > f . datalen  - =  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( diff  >  num_generations  & &  diff  <  10 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											len  - =  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > f . data . ptr  + =  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > f . datalen  - =  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											data  =  rtp - > f . data . ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* data + +  =  0xEF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* data + +  =  0xBF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* data  =  0xBD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  (  x  =  0 ;  x  <  num_generations  -  diff ;  x + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												len  + =  data [ x  *  4  +  3 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > f . data . ptr  + =  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > f . datalen  - =  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( rtp - > f . subclass . codec  &  AST_FORMAT_AUDIO_MASK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										rtp - > f . samples  =  ast_codec_get_samples ( & rtp - > f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( rtp - > f . subclass . codec  = =  AST_FORMAT_SLINEAR ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_frame_byteswap_be ( & rtp - > f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										calc_rxstamp ( & rtp - > f . delivery ,  rtp ,  timestamp ,  mark ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Add timing data to let ast_generic_bridge() put the frame into a jitterbuf */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_set_flag ( & rtp - > f ,  AST_FRFLAG_HAS_TIMING_INFO ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										rtp - > f . ts  =  timestamp  /  ( rtp_get_rate ( rtp - > f . subclass . codec )  /  1000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . len  =  rtp - > f . samples  /  ( ( ast_format_rate ( rtp - > f . subclass . codec )  /  1000 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( rtp - > f . subclass . codec  &  AST_FORMAT_VIDEO_MASK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Video -- samples is # of samples vs. 90000 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! rtp - > lastividtimestamp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > lastividtimestamp  =  timestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . samples  =  timestamp  -  rtp - > lastividtimestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > lastividtimestamp  =  timestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . delivery . tv_sec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . delivery . tv_usec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Pass the RTP marker bit as bit 0 in the subclass field.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  This  is  ok  because  subclass  is  actually  a  bitmask ,  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  the  low  bits  represent  audio  formats ,  that  are  not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  involved  here  since  we  deal  with  video . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( mark ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											rtp - > f . subclass . codec  | =  0x1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* TEXT -- samples is # of samples vs. 1000 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! rtp - > lastitexttimestamp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > lastitexttimestamp  =  timestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . samples  =  timestamp  -  rtp - > lastitexttimestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > lastitexttimestamp  =  timestamp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . delivery . tv_sec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > f . delivery . tv_usec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  & rtp - > f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  ast_rtp_prop_set ( struct  ast_rtp_instance  * instance ,  enum  ast_rtp_property  property ,  int  value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( property  = =  AST_RTP_PROPERTY_RTCP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( rtp - > rtcp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Ignoring duplicate RTCP property on RTP instance '%p' \n " ,  instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( rtp - > rtcp  =  ast_calloc ( 1 ,  sizeof ( * rtp - > rtcp ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( rtp - > rtcp - > s  =  create_new_socket ( " RTCP " ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Failed to create a new socket for RTCP on instance '%p' \n " ,  instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_free ( rtp - > rtcp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Grab the IP address and port we are going to use */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_rtp_instance_get_local_address ( instance ,  & rtp - > rtcp - > us ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > rtcp - > us . sin_port  =  htons ( ntohs ( rtp - > rtcp - > us . sin_port )  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Try to actually bind to the IP address and port we are going to use for RTCP, if this fails we have to bail out */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( bind ( rtp - > rtcp - > s ,  ( struct  sockaddr * ) & rtp - > rtcp - > us ,  sizeof ( rtp - > rtcp - > us ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Failed to setup RTCP on RTP instance '%p' \n " ,  instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											close ( rtp - > rtcp - > s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_free ( rtp - > rtcp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtp - > rtcp  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Setup RTCP on RTP instance '%p' \n " ,  instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > rtcp - > schedid  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_fd ( struct  ast_rtp_instance  * instance ,  int  rtcp )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  rtcp  ?  ( rtp - > rtcp  ?  rtp - > rtcp - > s  :  - 1 )  :  rtp - > s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  ast_rtp_remote_address_set ( struct  ast_rtp_instance  * instance ,  struct  sockaddr_in  * sin )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > rtcp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Setting RTCP address on RTP instance '%p' \n " ,  instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memcpy ( & rtp - > rtcp - > them ,  sin ,  sizeof ( rtp - > rtcp - > them ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > rtcp - > them . sin_port  =  htons ( ntohs ( sin - > sin_port )  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > rxseqno  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( strictrtp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > strict_rtp_state  =  STRICT_RTP_LEARN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-18 15:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  ast_rtp_alt_remote_address_set ( struct  ast_rtp_instance  * instance ,  struct  sockaddr_in  * sin )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* No need to futz with rtp->rtcp here because ast_rtcp_read is already able to adjust if receiving
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  RTCP  from  an  " unexpected "  source 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > alt_rtp_address  =  * sin ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*! \brief Write t140 redundacy frame
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  data  primary  data  to  be  buffered 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  red_write ( const  void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp_instance  * instance  =  ( struct  ast_rtp_instance * )  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rtp_write ( instance ,  & rtp - > red - > t140 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtp_red_init ( struct  ast_rtp_instance  * instance ,  int  buffer_time ,  int  * payloads ,  int  generations )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( rtp - > red  =  ast_calloc ( 1 ,  sizeof ( * rtp - > red ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > red - > t140 . frametype  =  AST_FRAME_TEXT ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rtp - > red - > t140 . subclass . codec  =  AST_FORMAT_T140RED ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									rtp - > red - > t140 . data . ptr  =  & rtp - > red - > buf_data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > red - > t140 . ts  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > red - > t140red  =  rtp - > red - > t140 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > red - > t140red . data . ptr  =  & rtp - > red - > t140red_data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > red - > t140red . datalen  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > red - > ti  =  buffer_time ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > red - > num_gen  =  generations ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > red - > hdrlen  =  generations  *  4  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > red - > prev_ts  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( x  =  0 ;  x  <  generations ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > red - > pt [ x ]  =  payloads [ x ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > red - > pt [ x ]  | =  1  < <  7 ;  /* mark redundant generations pt */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > red - > t140red_data [ x * 4 ]  =  rtp - > red - > pt [ x ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > red - > t140red_data [ x * 4 ]  =  rtp - > red - > pt [ x ]  =  payloads [ x ] ;  /* primary pt */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > red - > schedid  =  ast_sched_add ( rtp - > sched ,  generations ,  red_write ,  instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp - > red - > t140 . datalen  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtp_red_buffer ( struct  ast_rtp_instance  * instance ,  struct  ast_frame  * frame )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( frame - > datalen  >  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  rtp_red  * red  =  rtp - > red ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memcpy ( & red - > buf_data [ red - > t140 . datalen ] ,  frame - > data . ptr ,  frame - > datalen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										red - > t140 . datalen  + =  frame - > datalen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										red - > t140 . ts  =  frame - > ts ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_local_bridge ( struct  ast_rtp_instance  * instance0 ,  struct  ast_rtp_instance  * instance1 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_set_flag ( rtp ,  FLAG_NEED_MARKER_BIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_get_stat ( struct  ast_rtp_instance  * instance ,  struct  ast_rtp_instance_stats  * stats ,  enum  ast_rtp_instance_stat  stat )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! rtp - > rtcp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_TXCOUNT ,  - 1 ,  stats - > txcount ,  rtp - > txcount ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_RXCOUNT ,  - 1 ,  stats - > rxcount ,  rtp - > rxcount ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_TXPLOSS ,  AST_RTP_INSTANCE_STAT_COMBINED_LOSS ,  stats - > txploss ,  rtp - > rtcp - > reported_lost ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_RXPLOSS ,  AST_RTP_INSTANCE_STAT_COMBINED_LOSS ,  stats - > rxploss ,  rtp - > rtcp - > expected_prior  -  rtp - > rtcp - > received_prior ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_REMOTE_MAXRXPLOSS ,  AST_RTP_INSTANCE_STAT_COMBINED_LOSS ,  stats - > remote_maxrxploss ,  rtp - > rtcp - > reported_maxlost ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_REMOTE_MINRXPLOSS ,  AST_RTP_INSTANCE_STAT_COMBINED_LOSS ,  stats - > remote_minrxploss ,  rtp - > rtcp - > reported_minlost ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVRXPLOSS ,  AST_RTP_INSTANCE_STAT_COMBINED_LOSS ,  stats - > remote_normdevrxploss ,  rtp - > rtcp - > reported_normdev_lost ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_REMOTE_STDEVRXPLOSS ,  AST_RTP_INSTANCE_STAT_COMBINED_LOSS ,  stats - > remote_stdevrxploss ,  rtp - > rtcp - > reported_stdev_lost ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_LOCAL_MAXRXPLOSS ,  AST_RTP_INSTANCE_STAT_COMBINED_LOSS ,  stats - > local_maxrxploss ,  rtp - > rtcp - > maxrxlost ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_LOCAL_MINRXPLOSS ,  AST_RTP_INSTANCE_STAT_COMBINED_LOSS ,  stats - > local_minrxploss ,  rtp - > rtcp - > minrxlost ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVRXPLOSS ,  AST_RTP_INSTANCE_STAT_COMBINED_LOSS ,  stats - > local_normdevrxploss ,  rtp - > rtcp - > normdev_rxlost ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_LOCAL_STDEVRXPLOSS ,  AST_RTP_INSTANCE_STAT_COMBINED_LOSS ,  stats - > local_stdevrxploss ,  rtp - > rtcp - > stdev_rxlost ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_TERMINATOR ( AST_RTP_INSTANCE_STAT_COMBINED_LOSS ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_TXJITTER ,  AST_RTP_INSTANCE_STAT_COMBINED_JITTER ,  stats - > txjitter ,  rtp - > rxjitter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_RXJITTER ,  AST_RTP_INSTANCE_STAT_COMBINED_JITTER ,  stats - > rxjitter ,  rtp - > rtcp - > reported_jitter  /  ( unsigned  int )  65536.0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_REMOTE_MAXJITTER ,  AST_RTP_INSTANCE_STAT_COMBINED_JITTER ,  stats - > remote_maxjitter ,  rtp - > rtcp - > reported_maxjitter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_REMOTE_MINJITTER ,  AST_RTP_INSTANCE_STAT_COMBINED_JITTER ,  stats - > remote_minjitter ,  rtp - > rtcp - > reported_minjitter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVJITTER ,  AST_RTP_INSTANCE_STAT_COMBINED_JITTER ,  stats - > remote_normdevjitter ,  rtp - > rtcp - > reported_normdev_jitter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_REMOTE_STDEVJITTER ,  AST_RTP_INSTANCE_STAT_COMBINED_JITTER ,  stats - > remote_stdevjitter ,  rtp - > rtcp - > reported_stdev_jitter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_LOCAL_MAXJITTER ,  AST_RTP_INSTANCE_STAT_COMBINED_JITTER ,  stats - > local_maxjitter ,  rtp - > rtcp - > maxrxjitter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_LOCAL_MINJITTER ,  AST_RTP_INSTANCE_STAT_COMBINED_JITTER ,  stats - > local_minjitter ,  rtp - > rtcp - > minrxjitter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVJITTER ,  AST_RTP_INSTANCE_STAT_COMBINED_JITTER ,  stats - > local_normdevjitter ,  rtp - > rtcp - > normdev_rxjitter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_LOCAL_STDEVJITTER ,  AST_RTP_INSTANCE_STAT_COMBINED_JITTER ,  stats - > local_stdevjitter ,  rtp - > rtcp - > stdev_rxjitter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_TERMINATOR ( AST_RTP_INSTANCE_STAT_COMBINED_JITTER ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_RTT ,  AST_RTP_INSTANCE_STAT_COMBINED_RTT ,  stats - > rtt ,  rtp - > rtcp - > rtt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_MAX_RTT ,  AST_RTP_INSTANCE_STAT_COMBINED_RTT ,  stats - > maxrtt ,  rtp - > rtcp - > maxrtt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_MIN_RTT ,  AST_RTP_INSTANCE_STAT_COMBINED_RTT ,  stats - > minrtt ,  rtp - > rtcp - > minrtt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_NORMDEVRTT ,  AST_RTP_INSTANCE_STAT_COMBINED_RTT ,  stats - > normdevrtt ,  rtp - > rtcp - > normdevrtt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_STDEVRTT ,  AST_RTP_INSTANCE_STAT_COMBINED_RTT ,  stats - > stdevrtt ,  rtp - > rtcp - > stdevrtt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_TERMINATOR ( AST_RTP_INSTANCE_STAT_COMBINED_RTT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_LOCAL_SSRC ,  - 1 ,  stats - > local_ssrc ,  rtp - > ssrc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RTP_STAT_SET ( AST_RTP_INSTANCE_STAT_REMOTE_SSRC ,  - 1 ,  stats - > remote_ssrc ,  rtp - > themssrc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  ast_rtp_dtmf_compatible ( struct  ast_channel  * chan0 ,  struct  ast_rtp_instance  * instance0 ,  struct  ast_channel  * chan1 ,  struct  ast_rtp_instance  * instance1 )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If both sides are not using the same method of DTMF transmission
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  ( ie :  one  is  RFC2833 ,  other  is  INFO . . .  then  we  can  not  do  direct  media . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  |  DTMF  Mode  |   HAS_DTMF   |   Accepts  Begin  Frames  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  | - - - - - - - - - - - | - - - - - - - - - - - - | - - - - - - - - - - - - - - - - - - - - - - - | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  |  Inband     |  False       |  True                   | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  |  RFC2833    |  True        |  True                   | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  |  SIP  INFO   |  False       |  False                  | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ( ( ( ast_rtp_instance_get_prop ( instance0 ,  AST_RTP_PROPERTY_DTMF )  ! =  ast_rtp_instance_get_prop ( instance1 ,  AST_RTP_PROPERTY_DTMF ) )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 ( ! chan0 - > tech - > send_digit_begin  ! =  ! chan1 - > tech - > send_digit_begin ) )  ?  0  :  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  ast_rtp_stun_request ( struct  ast_rtp_instance  * instance ,  struct  sockaddr_in  * suggestion ,  const  char  * username )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_stun_request ( rtp - > s ,  suggestion ,  username ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  ast_rtp_stop ( struct  ast_rtp_instance  * instance )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_rtp  * rtp  =  ast_rtp_instance_get_data ( instance ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  sockaddr_in  sin  =  {  0 ,  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > rtcp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_SCHED_DEL ( rtp - > sched ,  rtp - > rtcp - > schedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > red )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_SCHED_DEL ( rtp - > sched ,  rtp - > red - > schedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										free ( rtp - > red ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtp - > red  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rtp_instance_set_remote_address ( instance ,  & sin ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtp - > rtcp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memset ( & rtp - > rtcp - > them . sin_addr ,  0 ,  sizeof ( rtp - > rtcp - > them . sin_addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memset ( & rtp - > rtcp - > them . sin_port ,  0 ,  sizeof ( rtp - > rtcp - > them . sin_port ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_set_flag ( rtp ,  FLAG_NEED_MARKER_BIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * rtp_do_debug_ip ( struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  hostent  * hp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_hostent  ahp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  port  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-12 13:08:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * p ,  * arg  =  ast_strdupa ( a - > argv [ 4 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p  =  strstr ( arg ,  " : " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* p  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										port  =  atoi ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hp  =  ast_gethostbyname ( arg ,  & ahp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hp  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " Lookup failed for '%s' \n " ,  arg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_FAILURE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpdebugaddr . sin_family  =  AF_INET ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memcpy ( & rtpdebugaddr . sin_addr ,  hp - > h_addr ,  sizeof ( rtpdebugaddr . sin_addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpdebugaddr . sin_port  =  htons ( port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( port  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " RTP Debugging Enabled for IP: %s \n " ,  ast_inet_ntoa ( rtpdebugaddr . sin_addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " RTP Debugging Enabled for IP: %s:%d \n " ,  ast_inet_ntoa ( rtpdebugaddr . sin_addr ) ,  port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpdebug  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * rtcp_do_debug_ip ( struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  hostent  * hp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_hostent  ahp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  port  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-21 21:13:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * p ,  * arg  =  ast_strdupa ( a - > argv [ 3 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p  =  strstr ( arg ,  " : " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* p  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										port  =  atoi ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									hp  =  ast_gethostbyname ( arg ,  & ahp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( hp  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " Lookup failed for '%s' \n " ,  arg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_FAILURE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpdebugaddr . sin_family  =  AF_INET ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memcpy ( & rtcpdebugaddr . sin_addr ,  hp - > h_addr ,  sizeof ( rtcpdebugaddr . sin_addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpdebugaddr . sin_port  =  htons ( port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( port  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " RTCP Debugging Enabled for IP: %s \n " ,  ast_inet_ntoa ( rtcpdebugaddr . sin_addr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " RTCP Debugging Enabled for IP: %s:%d \n " ,  ast_inet_ntoa ( rtcpdebugaddr . sin_addr ) ,  port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtcpdebug  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_cli_rtp_set_debug ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " rtp set debug {on|off|ip} " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: rtp set debug {on|off|ip host[:port]} \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        Enable/Disable dumping of all RTP packets. If 'ip' is \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        specified, limit the dumped packets to those to and from \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        the specified 'host' with optional port. \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a - > argc  = =  e - > args )  {  /* set on or off */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strncasecmp ( a - > argv [ e - > args - 1 ] ,  " on " ,  2 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtpdebug  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memset ( & rtpdebugaddr ,  0 ,  sizeof ( rtpdebugaddr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cli ( a - > fd ,  " RTP Debugging Enabled \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strncasecmp ( a - > argv [ e - > args - 1 ] ,  " off " ,  3 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtpdebug  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cli ( a - > fd ,  " RTP Debugging Disabled \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( a - > argc  = =  e - > args  + 1 )  {  /* ip */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  rtp_do_debug_ip ( a ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SHOWUSAGE ;    /* default, failure */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_cli_rtcp_set_debug ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " rtcp set debug {on|off|ip} " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: rtcp set debug {on|off|ip host[:port]} \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        Enable/Disable dumping of all RTCP packets. If 'ip' is \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        specified, limit the dumped packets to those to and from \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        the specified 'host' with optional port. \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a - > argc  = =  e - > args )  {  /* set on or off */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strncasecmp ( a - > argv [ e - > args - 1 ] ,  " on " ,  2 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtcpdebug  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memset ( & rtcpdebugaddr ,  0 ,  sizeof ( rtcpdebugaddr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cli ( a - > fd ,  " RTCP Debugging Enabled \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strncasecmp ( a - > argv [ e - > args - 1 ] ,  " off " ,  3 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtcpdebug  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cli ( a - > fd ,  " RTCP Debugging Disabled \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( a - > argc  = =  e - > args  + 1 )  {  /* ip */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  rtcp_do_debug_ip ( a ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SHOWUSAGE ;    /* default, failure */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_cli_rtcp_set_stats ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " rtcp set stats {on|off} " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: rtcp set stats {on|off} \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        Enable/Disable dumping of RTCP stats. \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( a - > argc  ! =  e - > args ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_SHOWUSAGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! strncasecmp ( a - > argv [ e - > args - 1 ] ,  " on " ,  2 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtcpstats  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else  if  ( ! strncasecmp ( a - > argv [ e - > args - 1 ] ,  " off " ,  3 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtcpstats  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_SHOWUSAGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  " RTCP Stats %s \n " ,  rtcpstats  ?  " Enabled "  :  " Disabled " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_cli_entry  cli_rtp [ ]  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_cli_rtp_set_debug ,   " Enable/Disable RTP debugging " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_cli_rtcp_set_debug ,  " Enable/Disable RTCP debugging " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_cli_rtcp_set_stats ,  " Enable/Disable RTCP stats " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  rtp_reload ( int  reload )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_config  * cfg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * s ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_flags  config_flags  =  {  reload  ?  CONFIG_FLAG_FILEUNCHANGED  :  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									cfg  =  ast_config_load2 ( " rtp.conf " ,  " rtp " ,  config_flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( cfg  = =  CONFIG_STATUS_FILEMISSING  | |  cfg  = =  CONFIG_STATUS_FILEUNCHANGED  | |  cfg  = =  CONFIG_STATUS_FILEINVALID )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpstart  =  DEFAULT_RTP_START ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtpend  =  DEFAULT_RTP_END ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									dtmftimeout  =  DEFAULT_DTMF_TIMEOUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									strictrtp  =  STRICT_RTP_OPEN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( cfg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( s  =  ast_variable_retrieve ( cfg ,  " general " ,  " rtpstart " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtpstart  =  atoi ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtpstart  <  MINIMUM_RTP_PORT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtpstart  =  MINIMUM_RTP_PORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtpstart  >  MAXIMUM_RTP_PORT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtpstart  =  MAXIMUM_RTP_PORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( s  =  ast_variable_retrieve ( cfg ,  " general " ,  " rtpend " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtpend  =  atoi ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtpend  <  MINIMUM_RTP_PORT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtpend  =  MINIMUM_RTP_PORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtpend  >  MAXIMUM_RTP_PORT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtpend  =  MAXIMUM_RTP_PORT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( s  =  ast_variable_retrieve ( cfg ,  " general " ,  " rtcpinterval " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rtcpinterval  =  atoi ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtcpinterval  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtcpinterval  =  0 ;  /* Just so we're clear... it's zero */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtcpinterval  <  RTCP_MIN_INTERVALMS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtcpinterval  =  RTCP_MIN_INTERVALMS ;  /* This catches negative numbers too */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( rtcpinterval  >  RTCP_MAX_INTERVALMS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rtcpinterval  =  RTCP_MAX_INTERVALMS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( s  =  ast_variable_retrieve ( cfg ,  " general " ,  " rtpchecksums " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef SO_NO_CHECK 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											nochecksums  =  ast_false ( s )  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# else 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_false ( s ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Disabling RTP checksums is not supported on this operating system! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( s  =  ast_variable_retrieve ( cfg ,  " general " ,  " dtmftimeout " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dtmftimeout  =  atoi ( s ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-13 13:39:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ( dtmftimeout  <  0 )  | |  ( dtmftimeout  >  64000 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-02 17:20:52 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " DTMF timeout of '%d' outside range, using default of '%d' instead \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													dtmftimeout ,  DEFAULT_DTMF_TIMEOUT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												dtmftimeout  =  DEFAULT_DTMF_TIMEOUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( s  =  ast_variable_retrieve ( cfg ,  " general " ,  " strictrtp " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											strictrtp  =  ast_true ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_config_destroy ( cfg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( rtpstart  > =  rtpend )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Unreasonable values for RTP start/end port in rtp.conf \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtpstart  =  DEFAULT_RTP_START ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rtpend  =  DEFAULT_RTP_END ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_verb ( 2 ,  " RTP Allocating from port range %d -> %d \n " ,  rtpstart ,  rtpend ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  reload_module ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp_reload ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  load_module ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_rtp_engine_register ( & asterisk_rtp_engine ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AST_MODULE_LOAD_DECLINE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_cli_register_multiple ( cli_rtp ,  ARRAY_LEN ( cli_rtp ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_rtp_engine_unregister ( & asterisk_rtp_engine ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AST_MODULE_LOAD_DECLINE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rtp_reload ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  AST_MODULE_LOAD_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  unload_module ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rtp_engine_unregister ( & asterisk_rtp_engine ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cli_unregister_multiple ( cli_rtp ,  ARRAY_LEN ( cli_rtp ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								AST_MODULE_INFO ( ASTERISK_GPL_KEY ,  AST_MODFLAG_DEFAULT ,  " Asterisk RTP Stack " ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. load  =  load_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. unload  =  unload_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. reload  =  reload_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										) ;