2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Asterisk  - -  An  open  source  telephony  toolkit . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( C )  1999  -  2009 ,  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
  
						 
					
						
							
								
									
										
										
										
											2009-08-03 16:24:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Analog  signaling  module 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ author  Matthew  Fredrickson  < creslin @ digium . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-06-15 16:20:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*** MODULEINFO
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< support_level > core < / support_level > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "asterisk.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <errno.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <ctype.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/utils.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/options.h" 
  
						 
					
						
							
								
									
										
										
										
											2013-08-02 04:48:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/pickup.h" 
  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/pbx.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/file.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/callerid.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/say.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/manager.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/astdb.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/features.h" 
  
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/causes.h" 
  
						 
					
						
							
								
									
										
										
										
											2013-06-06 21:40:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/features_config.h" 
  
						 
					
						
							
								
									
										
										
										
											2013-07-25 04:06:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/bridge.h" 
  
						 
					
						
							
								
									
										
										
										
											2013-08-01 20:55:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/parking.h" 
  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "sig_analog.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-11 02:06:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*** DOCUMENTATION
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 17:44:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \note
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Define  if  you  want  to  check  the  hook  state  for  an  FXO  ( FXS  signalled )  interface 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  before  dialing  on  it .   Certain  FXO  interfaces  always  think  they ' re  out  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  service  with  this  method  however . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* #define DAHDI_CHECK_HOOKSTATE */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# define POLARITY_IDLE 0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define POLARITY_REV    1 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define MIN_MS_SINCE_FLASH			( (2000) )	 /*!< 2000 ms */ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  analog_defaultcic [ 64 ]  =  " " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  analog_defaultozz [ 64 ]  =  " " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									enum  analog_sigtype  sigtype ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-01 12:04:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * name ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  sigtypes [ ]  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_FXOLS ,  " fxo_ls "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_FXOKS ,  " fxo_ks "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_FXOGS ,  " fxo_gs "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_FXSLS ,  " fxs_ls "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_FXSKS ,  " fxs_ks "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_FXSGS ,  " fxs_gs "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_EMWINK ,  " em_w "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_EM ,  " em "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_EM_E1 ,  " em_e1 "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_FEATD ,  " featd "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_FEATDMF ,  " featdmf "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_FEATDMF_TA ,  " featdmf_ta "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_FEATB ,  " featb "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_FGC_CAMA ,  " fgccama "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_FGC_CAMAMF ,  " fgccamamf "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_SF ,  " sf "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_SFWINK ,  " sf_w "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_SF_FEATD ,  " sf_featd "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_SF_FEATDMF ,  " sf_featdmf "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_SF_FEATB ,  " sf_featb "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  ANALOG_SIG_E911 ,  " e911 "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  int  cid_type ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-01 12:04:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * name ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  cidtypes [ ]  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  CID_SIG_BELL ,    " bell "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  CID_SIG_V23 ,     " v23 "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  CID_SIG_V23_JP ,  " v23_jp "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  CID_SIG_DTMF ,    " dtmf "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* "smdi" is intentionally not supported here, as there is a much better
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  way  to  do  this  in  the  dialplan  now .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define ISTRUNK(p) ((p->sig == ANALOG_SIG_FXSLS) || (p->sig == ANALOG_SIG_FXSKS) || \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													( p - > sig  = =  ANALOG_SIG_FXSGS ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								enum  analog_sigtype  analog_str_to_sigtype ( const  char  * name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  ARRAY_LEN ( sigtypes ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( sigtypes [ i ] . name ,  name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  sigtypes [ i ] . sigtype ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  char  * analog_sigtype_to_str ( enum  analog_sigtype  sigtype )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  ARRAY_LEN ( sigtypes ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( sigtype  = =  sigtypes [ i ] . sigtype )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  sigtypes [ i ] . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  " Unknown " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								unsigned  int  analog_str_to_cidtype ( const  char  * name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  ARRAY_LEN ( cidtypes ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( cidtypes [ i ] . name ,  name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  cidtypes [ i ] . cid_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  char  * analog_cidtype_to_str ( unsigned  int  cid_type )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  ARRAY_LEN ( cidtypes ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( cid_type  = =  cidtypes [ i ] . cid_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  cidtypes [ i ] . name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  " Unknown " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_start_cid_detect ( struct  analog_pvt  * p ,  int  cid_signalling )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . start_cid_detect )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . start_cid_detect ( p - > chan_pvt ,  cid_signalling ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_stop_cid_detect ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . stop_cid_detect )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . stop_cid_detect ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_get_callerid ( struct  analog_pvt  * p ,  char  * name ,  char  * number ,  enum  analog_event  * ev ,  size_t  timeout )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . get_callerid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . get_callerid ( p - > chan_pvt ,  name ,  number ,  ev ,  timeout ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge Call completion support into trunk.
From Reviewboard:
CCSS stands for Call Completion Supplementary Services. An admittedly out-of-date
overview of the architecture can be found in the file doc/CCSS_architecture.pdf
in the CCSS branch. Off the top of my head, the big differences between what is
implemented and what is in the document are as follows:
1. We did not end up modifying the Hangup application at all.
2. The document states that a single call completion monitor may be used across
   multiple calls to the same device. This proved to not be such a good idea
   when implementing protocol-specific monitors, and so we ended up using one
   monitor per-device per-call.
3. There are some configuration options which were conceived after the document
   was written. These are documented in the ccss.conf.sample that is on this
   review request.
		      
For some basic understanding of terminology used throughout this code, see the
ccss.tex document that is on this review.
This implements CCBS and CCNR in several flavors.
First up is a "generic" implementation, which can work over any channel technology
provided that the channel technology can accurately report device state. Call
completion is requested using the dialplan application CallCompletionRequest and can
be canceled using CallCompletionCancel. Device state subscriptions are used in order
to monitor the state of called parties.
Next, there is a SIP-specific implementation of call completion. This method uses the
methods outlined in draft-ietf-bliss-call-completion-06 to implement call completion
using SIP signaling. There are a few things to note here:
* The agent/monitor terminology used throughout Asterisk sometimes is the reverse of
  what is defined in the referenced draft.
* Implementation of the draft required support for SIP PUBLISH. I attempted to write
  this in a generic-enough fashion such that if someone were to want to write PUBLISH
  support for other event packages, such as dialog-state or presence, most of the effort
  would be in writing callbacks specific to the event package.
* A subportion of supporting PUBLISH reception was that we had to implement a PIDF
  parser. The PIDF support added is a bit minimal. I first wrote a validation
  routine to ensure that the PIDF document is formatted properly. The rest of the
  PIDF reading is done in-line in the call-completion-specific PUBLISH-handling
  code. In other words, while there is PIDF support here, it is not in any state
  where it could easily be applied to other event packages as is.
Finally, there are a variety of ISDN-related call completion protocols supported. These
were written by Richard Mudgett, and as such I can't really say much about their
implementation. There are notes in the CHANGES file that indicate the ISDN protocols
over which call completion is supported.
Review: https://reviewboard.asterisk.org/r/523
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-04-09 15:31:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  char  * analog_get_orig_dialstring ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . get_orig_dialstring )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . get_orig_dialstring ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge Call completion support into trunk.
From Reviewboard:
CCSS stands for Call Completion Supplementary Services. An admittedly out-of-date
overview of the architecture can be found in the file doc/CCSS_architecture.pdf
in the CCSS branch. Off the top of my head, the big differences between what is
implemented and what is in the document are as follows:
1. We did not end up modifying the Hangup application at all.
2. The document states that a single call completion monitor may be used across
   multiple calls to the same device. This proved to not be such a good idea
   when implementing protocol-specific monitors, and so we ended up using one
   monitor per-device per-call.
3. There are some configuration options which were conceived after the document
   was written. These are documented in the ccss.conf.sample that is on this
   review request.
		      
For some basic understanding of terminology used throughout this code, see the
ccss.tex document that is on this review.
This implements CCBS and CCNR in several flavors.
First up is a "generic" implementation, which can work over any channel technology
provided that the channel technology can accurately report device state. Call
completion is requested using the dialplan application CallCompletionRequest and can
be canceled using CallCompletionCancel. Device state subscriptions are used in order
to monitor the state of called parties.
Next, there is a SIP-specific implementation of call completion. This method uses the
methods outlined in draft-ietf-bliss-call-completion-06 to implement call completion
using SIP signaling. There are a few things to note here:
* The agent/monitor terminology used throughout Asterisk sometimes is the reverse of
  what is defined in the referenced draft.
* Implementation of the draft required support for SIP PUBLISH. I attempted to write
  this in a generic-enough fashion such that if someone were to want to write PUBLISH
  support for other event packages, such as dialog-state or presence, most of the effort
  would be in writing callbacks specific to the event package.
* A subportion of supporting PUBLISH reception was that we had to implement a PIDF
  parser. The PIDF support added is a bit minimal. I first wrote a validation
  routine to ensure that the PIDF document is formatted properly. The rest of the
  PIDF reading is done in-line in the call-completion-specific PUBLISH-handling
  code. In other words, while there is PIDF support here, it is not in any state
  where it could easily be applied to other event packages as is.
Finally, there are a variety of ISDN-related call completion protocols supported. These
were written by Richard Mudgett, and as such I can't really say much about their
implementation. There are notes in the CHANGES file that indicate the ISDN protocols
over which call completion is supported.
Review: https://reviewboard.asterisk.org/r/523
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-04-09 15:31:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  analog_get_event ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . get_event )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . get_event ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_wait_event ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . wait_event )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . wait_event ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-05 17:44:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  analog_have_progressdetect ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . have_progressdetect )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . have_progressdetect ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-05 17:44:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Don't have progress detection. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-03-21 14:30:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define gen_analog_field_callback(type, callback_name, def_value) \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									static  type  analog_get_ # # callback_name ( struct  analog_pvt  * p )  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! analog_callbacks . get_ # # callback_name )  {  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  def_value ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . get_ # # callback_name ( p - > chan_pvt ) ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								gen_analog_field_callback ( int ,  firstdigit_timeout ,  ANALOG_FIRST_DIGIT_TIMEOUT ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								gen_analog_field_callback ( int ,  interdigit_timeout ,  ANALOG_INTER_DIGIT_TIMEOUT ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								gen_analog_field_callback ( int ,  matchdigit_timeout ,  ANALOG_MATCH_DIGIT_TIMEOUT ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# undef gen_analog_field_callback 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								enum  analog_cid_start  analog_str_to_cidstart ( const  char  * value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! strcasecmp ( value ,  " ring " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ANALOG_CID_START_RING ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ! strcasecmp ( value ,  " polarity " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ANALOG_CID_START_POLARITY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ! strcasecmp ( value ,  " polarity_in " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ANALOG_CID_START_POLARITY_IN ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-03 19:40:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( ! strcasecmp ( value ,  " dtmf " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  ANALOG_CID_START_DTMF_NOALERT ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  char  * analog_cidstart_to_str ( enum  analog_cid_start  cid_start )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cid_start )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_CID_START_RING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " Ring " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_CID_START_POLARITY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " Polarity " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_CID_START_POLARITY_IN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " Polarity_In " ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-03 19:40:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ANALOG_CID_START_DTMF_NOALERT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  " DTMF " ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  " Unknown " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * analog_event2str ( enum  analog_event  event )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( event )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_ONHOOK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_ONHOOK " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_RINGOFFHOOK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_RINGOFFHOOK " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ANALOG_EVENT_WINKFLASH : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_WINKFLASH " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_ALARM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_ALARM " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_NOALARM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_NOALARM " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ANALOG_EVENT_DIALCOMPLETE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_DIALCOMPLETE " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_HOOKCOMPLETE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_HOOKCOMPLETE " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ANALOG_EVENT_PULSE_START : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_PULSE_START " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_POLARITY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_POLARITY " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ANALOG_EVENT_RINGBEGIN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_RINGBEGIN " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_EC_DISABLED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_EC_DISABLED " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_RINGERON : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_RINGERON " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_RINGEROFF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_RINGEROFF " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-14 22:38:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ANALOG_EVENT_REMOVED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_REMOVED " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_NEONMWI_ACTIVE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_NEONMWI_ACTIVE " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_NEONMWI_INACTIVE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_NEONMWI_INACTIVE " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_TX_CED_DETECTED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_TX_CED_DETECTED " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_RX_CED_DETECTED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_RX_CED_DETECTED " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_EC_NLP_DISABLED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_EC_NLP_DISABLED " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_EC_NLP_ENABLED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_EC_NLP_ENABLED " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_PULSEDIGIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_PULSEDIGIT " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_DTMFDOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_DTMFDOWN " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_DTMFUP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " ANALOG_EVENT_DTMFUP " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  " UNKNOWN/OTHER " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_swap_subs ( struct  analog_pvt  * p ,  enum  analog_sub  a ,  enum  analog_sub  b )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  tinthreeway ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * towner ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Swapping %u and %u \n " ,  a ,  b ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									towner  =  p - > subs [ a ] . owner ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ a ] . owner  =  p - > subs [ b ] . owner ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ b ] . owner  =  towner ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-01 17:32:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tinthreeway  =  p - > subs [ a ] . inthreeway ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ a ] . inthreeway  =  p - > subs [ b ] . inthreeway ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									p - > subs [ b ] . inthreeway  =  tinthreeway ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . swap_subs )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . swap_subs ( p - > chan_pvt ,  a ,  p - > subs [ a ] . owner ,  b ,  p - > subs [ b ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_alloc_sub ( struct  analog_pvt  * p ,  enum  analog_sub  x )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . allocate_sub )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-17 17:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										res  =  analog_callbacks . allocate_sub ( p - > chan_pvt ,  x ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-17 17:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p - > subs [ x ] . allocd  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-17 17:02:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_unalloc_sub ( struct  analog_pvt  * p ,  enum  analog_sub  x )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ x ] . allocd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ x ] . owner  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . unallocate_sub )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . unallocate_sub ( p - > chan_pvt ,  x ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  analog_send_callerid ( struct  analog_pvt  * p ,  int  cwcid ,  struct  ast_party_caller  * caller )  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Sending callerid.  CID_NAME: '%s' CID_NUM: '%s' \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										caller - > id . name . str , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										caller - > id . number . str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( cwcid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p - > callwaitcas  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . send_callerid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . send_callerid ( p - > chan_pvt ,  cwcid ,  caller ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-02 21:31:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define analog_get_index(ast, p, nullok)	_analog_get_index(ast, p, nullok, __PRETTY_FUNCTION__, __LINE__) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  _analog_get_index ( struct  ast_channel  * ast ,  struct  analog_pvt  * p ,  int  nullok ,  const  char  * fname ,  unsigned  long  line )  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p - > subs [ ANALOG_SUB_REAL ] . owner  = =  ast )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										res  =  ANALOG_SUB_REAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( p - > subs [ ANALOG_SUB_CALLWAIT ] . owner  = =  ast )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										res  =  ANALOG_SUB_CALLWAIT ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner  = =  ast )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										res  =  ANALOG_SUB_THREEWAY ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! nullok )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-02 21:31:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Unable to get index for '%s' on channel %d (%s(), line %lu) \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast  ?  ast_channel_name ( ast )  :  " " ,  p - > channel ,  fname ,  line ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_dsp_reset_and_flush_digits ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . dsp_reset_and_flush_digits )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . dsp_reset_and_flush_digits ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Return 0 since I think this is unnecessary to do in most cases it is used.  Mostly only for ast_dsp */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_play_tone ( struct  analog_pvt  * p ,  enum  analog_sub  sub ,  enum  analog_tone  tone )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . play_tone )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . play_tone ( p - > chan_pvt ,  sub ,  tone ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_set_new_owner ( struct  analog_pvt  * p ,  struct  ast_channel  * new_owner )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > owner  =  new_owner ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_new_owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . set_new_owner ( p - > chan_pvt ,  new_owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_channel  *  analog_new_ast_channel ( struct  analog_pvt  * p ,  int  state ,  int  startpbx ,  enum  analog_sub  sub ,  const  struct  ast_channel  * requestor )  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! analog_callbacks . new_ast_channel )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									c  =  analog_callbacks . new_ast_channel ( p - > chan_pvt ,  state ,  startpbx ,  sub ,  requestor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-15 22:48:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( c )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-24 20:12:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_call_forward_set ( c ,  p - > call_forward ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-15 22:48:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									p - > subs [ sub ] . owner  =  c ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! p - > owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_new_owner ( p ,  c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_set_echocanceller ( struct  analog_pvt  * p ,  int  enable )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_echocanceller )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . set_echocanceller ( p - > chan_pvt ,  enable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_train_echocanceller ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . train_echocanceller )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . train_echocanceller ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_is_off_hook ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . is_off_hook )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . is_off_hook ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_ring ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . ring )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . ring ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  analog_flash ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . flash )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . flash ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  analog_start ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . start )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . start ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_dial_digits ( struct  analog_pvt  * p ,  enum  analog_sub  sub ,  struct  analog_dialoperation  * dop )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . dial_digits )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . dial_digits ( p - > chan_pvt ,  sub ,  dop ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_on_hook ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . on_hook )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . on_hook ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-18 08:02:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_set_outgoing ( struct  analog_pvt  * p ,  int  is_outgoing )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > outgoing  =  is_outgoing ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_outgoing )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . set_outgoing ( p - > chan_pvt ,  is_outgoing ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-18 08:02:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  analog_check_for_conference ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . check_for_conference )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . check_for_conference ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_all_subchannels_hungup ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . all_subchannels_hungup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . all_subchannels_hungup ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_unlock_private ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . unlock_private )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . unlock_private ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_lock_private ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . lock_private )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . lock_private ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2011-04-08 16:17:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_deadlock_avoidance_private ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . deadlock_avoidance_private )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . deadlock_avoidance_private ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-08 16:17:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Fallback to manual avoidance if callback not present. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_unlock_private ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										usleep ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_lock_private ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Obtain  the  specified  subchannel  owner  lock  if  the  owner  exists . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  pvt  Analog  private  struct . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  sub_idx  Subchannel  owner  to  lock . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note  Assumes  the  analog_lock_private ( pvt - > chan_pvt )  is  already  obtained . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Because  deadlock  avoidance  may  have  been  necessary ,  you  need  to  confirm 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  state  of  things  before  continuing . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_lock_sub_owner ( struct  analog_pvt  * pvt ,  enum  analog_sub  sub_idx )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! pvt - > subs [ sub_idx ] . owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* No subchannel owner pointer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ast_channel_trylock ( pvt - > subs [ sub_idx ] . owner ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Got subchannel owner lock */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* We must unlock the private to avoid the possibility of a deadlock */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-08 16:17:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_deadlock_avoidance_private ( pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_off_hook ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . off_hook )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . off_hook ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-30 22:36:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_set_needringing ( struct  analog_pvt  * p ,  int  value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_needringing )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . set_needringing ( p - > chan_pvt ,  value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-30 22:36:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 23:14:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								#if 0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_set_polarity ( struct  analog_pvt  * p ,  int  value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_polarity )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . set_polarity ( p - > chan_pvt ,  value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 23:14:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_start_polarityswitch ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . start_polarityswitch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . start_polarityswitch ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 23:14:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_answer_polarityswitch ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . answer_polarityswitch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . answer_polarityswitch ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 23:14:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_hangup_polarityswitch ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . hangup_polarityswitch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . hangup_polarityswitch ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 23:14:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  int  analog_dsp_set_digitmode ( struct  analog_pvt  * p ,  enum  analog_dsp_digitmode  mode )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . dsp_set_digitmode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . dsp_set_digitmode ( p - > chan_pvt ,  mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_cb_handle_dtmf ( struct  analog_pvt  * p ,  struct  ast_channel  * ast ,  enum  analog_sub  analog_index ,  struct  ast_frame  * * dest )  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . handle_dtmf )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . handle_dtmf ( p - > chan_pvt ,  ast ,  analog_index ,  dest ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_wink ( struct  analog_pvt  * p ,  enum  analog_sub  index )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . wink )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . wink ( p - > chan_pvt ,  index ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_has_voicemail ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . has_voicemail )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . has_voicemail ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_is_dialing ( struct  analog_pvt  * p ,  enum  analog_sub  index )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . is_dialing )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . is_dialing ( p - > chan_pvt ,  index ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Attempt  to  transfer  3 - way  call . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  p  Analog  private  structure . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-07 01:06:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ note  On  entry  these  locks  are  held :  real - call ,  private ,  3 - way  call . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note  On  exit  these  locks  are  held :  real - call ,  private . 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-07 01:06:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ retval  0  on  success . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  on  error . 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-07 01:06:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  analog_attempt_transfer ( struct  analog_pvt  * p )  
						 
					
						
							
								
									
										
										
										
											2010-11-09 17:00:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * owner_real ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * owner_3way ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-07 01:06:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									enum  ast_transfer_result  xfer_res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-09 17:00:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-06-07 01:06:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									owner_real  =  ast_channel_ref ( p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									owner_3way  =  ast_channel_ref ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-09 17:00:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-06-07 01:06:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_verb ( 3 ,  " TRANSFERRING %s to %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_name ( owner_3way ) ,  ast_channel_name ( owner_real ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unlock ( owner_real ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unlock ( owner_3way ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									analog_unlock_private ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									xfer_res  =  ast_bridge_transfer_attended ( owner_3way ,  owner_real ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( xfer_res  ! =  AST_BRIDGE_TRANSFER_SUCCESS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_softhangup ( owner_3way ,  AST_SOFTHANGUP_DEV ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-07 01:06:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Must leave with these locked. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_lock ( owner_real ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									analog_lock_private ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unref ( owner_real ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unref ( owner_3way ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_update_conf ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  needconf  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Start with the obvious, general stuff */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( x  =  0 ;  x  <  3 ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Look for three way calls */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( p - > subs [ x ] . allocd )  & &  p - > subs [ x ] . inthreeway )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( analog_callbacks . conf_add )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_callbacks . conf_add ( p - > chan_pvt ,  x ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											needconf + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( analog_callbacks . conf_del )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_callbacks . conf_del ( p - > chan_pvt ,  x ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Updated conferencing on %d, with %d conference users \n " ,  p - > channel ,  needconf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . complete_conference_update )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . complete_conference_update ( p - > chan_pvt ,  needconf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								struct  ast_channel  *  analog_request ( struct  analog_pvt  * p ,  int  * callwait ,  const  struct  ast_channel  * requestor )  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2010-09-15 18:30:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_channel  * ast ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " %s %d \n " ,  __FUNCTION__ ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									* callwait  =  ( p - > owner  ! =  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p - > owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( analog_alloc_sub ( p ,  ANALOG_SUB_CALLWAIT ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " Unable to alloc subchannel \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-18 08:02:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									analog_set_outgoing ( p ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-15 18:30:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast  =  analog_new_ast_channel ( p ,  AST_STATE_RESERVED ,  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p - > owner  ?  ANALOG_SUB_CALLWAIT  :  ANALOG_SUB_REAL ,  requestor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ast )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-18 08:02:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_outgoing ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-15 18:30:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ast ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-03-10 16:55:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  analog_available ( struct  analog_pvt  * p )  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  offhook ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " %s %d \n " ,  __FUNCTION__ ,  p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* If do not disturb, definitely not */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p - > dnd )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* If guard time, definitely not */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p - > guardtime  & &  ( time ( NULL )  <  p - > guardtime ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If no owner definitely available */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! p - > owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										offhook  =  analog_is_off_hook ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 17:44:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* TDM FXO card, "onhook" means out of service (no battery on the line) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( p - > sig  = =  ANALOG_SIG_FXSLS )  | |  ( p - > sig  = =  ANALOG_SIG_FXSKS )  | |  ( p - > sig  = =  ANALOG_SIG_FXSGS ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef DAHDI_CHECK_HOOKSTATE 
  
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( offhook )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-21 17:44:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* TDM FXS card, "offhook" means someone took the hook off so it's unavailable! */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										}  else  if  ( offhook )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Channel %d off hook, can't use \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Not available when the other end is off hook */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If it's not an FXO, forget about call wait */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( p - > sig  ! =  ANALOG_SIG_FXOKS )  & &  ( p - > sig  ! =  ANALOG_SIG_FXOLS )  & &  ( p - > sig  ! =  ANALOG_SIG_FXOGS ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! p - > callwaiting )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* If they don't have call waiting enabled, then for sure they're unavailable at this point */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p - > subs [ ANALOG_SUB_CALLWAIT ] . allocd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* If there is already a call waiting call, then we can't take a second one */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( ast_channel_state ( p - > owner )  ! =  AST_STATE_UP )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									    ( ( ast_channel_state ( p - > owner )  ! =  AST_STATE_RINGING )  | |  p - > outgoing ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* If the current call is not up, then don't allow the call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner )  & &  ( ! p - > subs [ ANALOG_SUB_THREEWAY ] . inthreeway ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Can't take a call wait when the three way calling hasn't been merged yet. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* We're cool */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_stop_callwait ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p - > callwaitcas  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . stop_callwait )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . stop_callwait ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_callwait ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p - > callwaitcas  =  p - > callwaitingcallerid ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . callwait )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . callwait ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_set_callwaiting ( struct  analog_pvt  * p ,  int  callwaiting_enable )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > callwaiting  =  callwaiting_enable ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_callwaiting )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . set_callwaiting ( p - > chan_pvt ,  callwaiting_enable ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_set_cadence ( struct  analog_pvt  * p ,  struct  ast_channel  * chan )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_cadence )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . set_cadence ( p - > chan_pvt ,  & p - > cidrings ,  chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-04 21:10:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_set_dialing ( struct  analog_pvt  * p ,  int  is_dialing )  
						 
					
						
							
								
									
										
										
										
											2009-07-15 22:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2010-05-04 21:10:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p - > dialing  =  is_dialing ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_dialing )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . set_dialing ( p - > chan_pvt ,  is_dialing ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-04 21:10:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_set_alarm ( struct  analog_pvt  * p ,  int  in_alarm )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > inalarm  =  in_alarm ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_alarm )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . set_alarm ( p - > chan_pvt ,  in_alarm ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 22:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-12 20:47:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_set_ringtimeout ( struct  analog_pvt  * p ,  int  ringt )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > ringt  =  ringt ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_ringtimeout )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . set_ringtimeout ( p - > chan_pvt ,  ringt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-12 20:47:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 22:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_set_waitingfordt ( struct  analog_pvt  * p ,  struct  ast_channel  * ast )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_waitingfordt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . set_waitingfordt ( p - > chan_pvt ,  ast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 22:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_check_waitingfordt ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . check_waitingfordt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . check_waitingfordt ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 22:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_set_confirmanswer ( struct  analog_pvt  * p ,  int  flag )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_confirmanswer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . set_confirmanswer ( p - > chan_pvt ,  flag ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 22:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_check_confirmanswer ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . check_confirmanswer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . check_confirmanswer ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 22:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-10 20:18:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_cancel_cidspill ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . cancel_cidspill )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . cancel_cidspill ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-10 20:18:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  analog_confmute ( struct  analog_pvt  * p ,  int  mute )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . confmute )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . confmute ( p - > chan_pvt ,  mute ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_set_pulsedial ( struct  analog_pvt  * p ,  int  flag )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_pulsedial )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . set_pulsedial ( p - > chan_pvt ,  flag ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-01 17:32:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  analog_set_linear_mode ( struct  analog_pvt  * p ,  enum  analog_sub  sub ,  int  linear_mode )  
						 
					
						
							
								
									
										
										
										
											2009-08-14 22:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_linear_mode )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-02 19:49:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Return provides old linear_mode setting or error indication */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  analog_callbacks . set_linear_mode ( p - > chan_pvt ,  sub ,  linear_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 22:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-01 17:32:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_set_inthreeway ( struct  analog_pvt  * p ,  enum  analog_sub  sub ,  int  inthreeway )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ sub ] . inthreeway  =  inthreeway ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . set_inthreeway )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . set_inthreeway ( p - > chan_pvt ,  sub ,  inthreeway ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-01 17:32:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-01 19:53:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  analog_call ( struct  analog_pvt  * p ,  struct  ast_channel  * ast ,  const  char  * rdest ,  int  timeout )  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  res ,  idx ,  mysig ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									char  * c ,  * n ,  * l ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  dest [ 256 ] ;  /* must be same length as p->dialdest */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " CALLING CID_NAME: %s CID_NUM:: %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										S_COR ( ast_channel_connected ( ast ) - > id . name . valid ,  ast_channel_connected ( ast ) - > id . name . str ,  " " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										S_COR ( ast_channel_connected ( ast ) - > id . number . valid ,  ast_channel_connected ( ast ) - > id . number . str ,  " " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_copy_string ( dest ,  rdest ,  sizeof ( dest ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_copy_string ( p - > dialdest ,  rdest ,  sizeof ( p - > dialdest ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( ast_channel_state ( ast )  = =  AST_STATE_BUSY ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_queue_control ( p - > subs [ ANALOG_SUB_REAL ] . owner ,  AST_CONTROL_BUSY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( ast_channel_state ( ast )  ! =  AST_STATE_DOWN )  & &  ( ast_channel_state ( ast )  ! =  AST_STATE_RESERVED ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " analog_call called on %s, neither down nor reserved \n " ,  ast_channel_name ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > dialednone  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-18 08:02:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									analog_set_outgoing ( p ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									mysig  =  p - > sig ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p - > outsigmod  >  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										mysig  =  p - > outsigmod ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( mysig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXOLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXOGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXOKS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p - > owner  = =  ast )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Normal ring, on hook */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Don't send audio while on hook, until the call is answered */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 22:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_set_dialing ( p ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_set_cadence ( p ,  ast ) ;  /* and set p->cidrings */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* nick@dccinc.com 4/3/03 mods to allow for deferred dialing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c  =  strchr ( dest ,  ' / ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( c )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												c + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( c  & &  ( strlen ( c )  <  p - > stripmsd ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Number '%s' is shorter than stripmsd (%d) \n " ,  c ,  p - > stripmsd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												c  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-03 06:57:58 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( c  & &  ( strlen ( c )  >  sizeof ( p - > dop . dialstr )  -  3  /* "Tw\0" */ ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Number '%s' is longer than %d bytes \n " ,  c ,  ( int ) sizeof ( p - > dop . dialstr )  -  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												c  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( c )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > dop . op  =  ANALOG_DIAL_OP_REPLACE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												snprintf ( p - > dop . dialstr ,  sizeof ( p - > dop . dialstr ) ,  " Tw%s " ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " FXO: setup deferred dialstring: %s \n " ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > dop . dialstr [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( analog_ring ( p ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Unable to ring phone: %s \n " ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 22:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_set_dialing ( p ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Call waiting call */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ast_channel_connected ( ast ) - > id . number . valid  & &  ast_channel_connected ( ast ) - > id . number . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_copy_string ( p - > callwait_num ,  ast_channel_connected ( ast ) - > id . number . str ,  sizeof ( p - > callwait_num ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												p - > callwait_num [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ast_channel_connected ( ast ) - > id . name . valid  & &  ast_channel_connected ( ast ) - > id . name . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_copy_string ( p - > callwait_name ,  ast_channel_connected ( ast ) - > id . name . str ,  sizeof ( p - > callwait_name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												p - > callwait_name [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Call waiting tone instead */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( analog_callwait ( p ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Make ring-back */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( analog_play_tone ( p ,  ANALOG_SUB_CALLWAIT ,  ANALOG_TONE_RINGTONE ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Unable to generate call-wait ring-back on channel %s \n " ,  ast_channel_name ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:29:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Name and Number */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										n  =  ast_channel_connected ( ast ) - > id . name . valid  ?  ast_channel_connected ( ast ) - > id . name . str  :  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										l  =  ast_channel_connected ( ast ) - > id . number . valid  ?  ast_channel_connected ( ast ) - > id . number . str  :  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( l )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( p - > lastcid_num ,  l ,  sizeof ( p - > lastcid_num ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											p - > lastcid_num [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( n )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( p - > lastcid_name ,  n ,  sizeof ( p - > lastcid_name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											p - > lastcid_name [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p - > use_callerid )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:29:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											const  char  * qual_var ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Caller ID Name and Number */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p - > caller . id . name . str  =  p - > lastcid_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > caller . id . number . str  =  p - > lastcid_num ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												chan_dahdi: Fix buggy and missing Caller ID parameters
There are several things wrong with analog Caller ID
handling that are fixed by this commit:
callerid.c's Caller ID generation function contains the
logic to use the presentation to properly send the proper
Caller ID. However, currently, DAHDI does not pass any
presentation information to the Caller ID module, which
means that presentation is completely ignored on all calls.
This means that lines could be getting Caller ID information
they aren't supposed to.
Part of the reason this has been obscured is because the
simple switch logic for handling the built in *67 and *82
is completely wrong. Rather than modifying the presentation
for the call accordingly (which is what it's supposed to do),
it simply blanks out the Caller ID or fills it in. This is
wrong, so wrong that it makes a mockery of the specification.
Additionally, it would leave to the "UNAVAILABLE" disposition
being used for Caller ID generation as opposed to the "PRIVATE"
disposition that it should have been using. This is now fixed
to only update the presentation and not modify the number and
name, so that the simple switch *67/*82 work correctly.
Next, sig_analog currently only copies over the name and number,
nothing else, when it is filling in a duplicated caller id
structure. Thus, we also now copy over the presentation
information so that is available for the Caller ID spill.
Additionally, this meant that "valid" was implicitly 0,
and as such presentation would always fail to "Unavailable".
The validity is therefore also copied over so it can be used
by ast_party_id_presentation.
As part of this fix, new API is added so that all the relevant
Caller ID information can be passed in to the Caller ID generation
functions. Parameters that are also completely missing from the
Caller ID spill have also been added, to enhance the compatibility,
correctness, and completeness of the Asterisk Caller ID implementation.
ASTERISK-29991 #close
Change-Id: Icc44a5e09979916f4c18a440f96e10dc1c76ae15
											 
										 
										
											2022-03-29 01:35:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p - > caller . id . name . valid  =  ast_channel_connected ( ast ) - > id . name . valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > caller . id . number . valid  =  ast_channel_connected ( ast ) - > id . number . valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > caller . id . name . presentation  =  ast_channel_connected ( ast ) - > id . name . presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > caller . id . number . presentation  =  ast_channel_connected ( ast ) - > id . number . presentation ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:29:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Redirecting Reason */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > redirecting_reason  =  ast_channel_redirecting ( ast ) - > from . number . valid  ?  ast_channel_redirecting ( ast ) - > reason . code  :  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Call Qualifier */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_channel_lock ( ast ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* XXX In the future, we may want to make this a CALLERID or CHANNEL property and fetch it from there. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											qual_var  =  pbx_builtin_getvar_helper ( ast ,  " CALL_QUALIFIER " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > call_qualifier  =  ast_true ( qual_var )  ?  1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_channel_unlock ( ast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_setstate ( ast ,  AST_STATE_RINGING ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										idx  =  analog_get_index ( ast ,  p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( idx  >  - 1 )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge Call completion support into trunk.
From Reviewboard:
CCSS stands for Call Completion Supplementary Services. An admittedly out-of-date
overview of the architecture can be found in the file doc/CCSS_architecture.pdf
in the CCSS branch. Off the top of my head, the big differences between what is
implemented and what is in the document are as follows:
1. We did not end up modifying the Hangup application at all.
2. The document states that a single call completion monitor may be used across
   multiple calls to the same device. This proved to not be such a good idea
   when implementing protocol-specific monitors, and so we ended up using one
   monitor per-device per-call.
3. There are some configuration options which were conceived after the document
   was written. These are documented in the ccss.conf.sample that is on this
   review request.
		      
For some basic understanding of terminology used throughout this code, see the
ccss.tex document that is on this review.
This implements CCBS and CCNR in several flavors.
First up is a "generic" implementation, which can work over any channel technology
provided that the channel technology can accurately report device state. Call
completion is requested using the dialplan application CallCompletionRequest and can
be canceled using CallCompletionCancel. Device state subscriptions are used in order
to monitor the state of called parties.
Next, there is a SIP-specific implementation of call completion. This method uses the
methods outlined in draft-ietf-bliss-call-completion-06 to implement call completion
using SIP signaling. There are a few things to note here:
* The agent/monitor terminology used throughout Asterisk sometimes is the reverse of
  what is defined in the referenced draft.
* Implementation of the draft required support for SIP PUBLISH. I attempted to write
  this in a generic-enough fashion such that if someone were to want to write PUBLISH
  support for other event packages, such as dialog-state or presence, most of the effort
  would be in writing callbacks specific to the event package.
* A subportion of supporting PUBLISH reception was that we had to implement a PIDF
  parser. The PIDF support added is a bit minimal. I first wrote a validation
  routine to ensure that the PIDF document is formatted properly. The rest of the
  PIDF reading is done in-line in the call-completion-specific PUBLISH-handling
  code. In other words, while there is PIDF support here, it is not in any state
  where it could easily be applied to other event packages as is.
Finally, there are a variety of ISDN-related call completion protocols supported. These
were written by Richard Mudgett, and as such I can't really say much about their
implementation. There are notes in the CHANGES file that indicate the ISDN protocols
over which call completion is supported.
Review: https://reviewboard.asterisk.org/r/523
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-04-09 15:31:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											struct  ast_cc_config_params  * cc_params ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* This is where the initial ringing frame is queued for an analog call.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  As  such ,  this  is  a  great  time  to  offer  CCNR  to  the  caller  if  it ' s  available . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											cc_params  =  ast_channel_get_cc_config_params ( p - > subs [ idx ] . owner ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge Call completion support into trunk.
From Reviewboard:
CCSS stands for Call Completion Supplementary Services. An admittedly out-of-date
overview of the architecture can be found in the file doc/CCSS_architecture.pdf
in the CCSS branch. Off the top of my head, the big differences between what is
implemented and what is in the document are as follows:
1. We did not end up modifying the Hangup application at all.
2. The document states that a single call completion monitor may be used across
   multiple calls to the same device. This proved to not be such a good idea
   when implementing protocol-specific monitors, and so we ended up using one
   monitor per-device per-call.
3. There are some configuration options which were conceived after the document
   was written. These are documented in the ccss.conf.sample that is on this
   review request.
		      
For some basic understanding of terminology used throughout this code, see the
ccss.tex document that is on this review.
This implements CCBS and CCNR in several flavors.
First up is a "generic" implementation, which can work over any channel technology
provided that the channel technology can accurately report device state. Call
completion is requested using the dialplan application CallCompletionRequest and can
be canceled using CallCompletionCancel. Device state subscriptions are used in order
to monitor the state of called parties.
Next, there is a SIP-specific implementation of call completion. This method uses the
methods outlined in draft-ietf-bliss-call-completion-06 to implement call completion
using SIP signaling. There are a few things to note here:
* The agent/monitor terminology used throughout Asterisk sometimes is the reverse of
  what is defined in the referenced draft.
* Implementation of the draft required support for SIP PUBLISH. I attempted to write
  this in a generic-enough fashion such that if someone were to want to write PUBLISH
  support for other event packages, such as dialog-state or presence, most of the effort
  would be in writing callbacks specific to the event package.
* A subportion of supporting PUBLISH reception was that we had to implement a PIDF
  parser. The PIDF support added is a bit minimal. I first wrote a validation
  routine to ensure that the PIDF document is formatted properly. The rest of the
  PIDF reading is done in-line in the call-completion-specific PUBLISH-handling
  code. In other words, while there is PIDF support here, it is not in any state
  where it could easily be applied to other event packages as is.
Finally, there are a variety of ISDN-related call completion protocols supported. These
were written by Richard Mudgett, and as such I can't really say much about their
implementation. There are notes in the CHANGES file that indicate the ISDN protocols
over which call completion is supported.
Review: https://reviewboard.asterisk.org/r/523
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-04-09 15:31:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( cc_params )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												switch  ( ast_get_cc_monitor_policy ( cc_params ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_CC_MONITOR_NEVER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_CC_MONITOR_NATIVE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_CC_MONITOR_ALWAYS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_CC_MONITOR_GENERIC : 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_queue_cc_frame ( p - > subs [ idx ] . owner ,  AST_CC_GENERIC_MONITOR_TYPE , 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge Call completion support into trunk.
From Reviewboard:
CCSS stands for Call Completion Supplementary Services. An admittedly out-of-date
overview of the architecture can be found in the file doc/CCSS_architecture.pdf
in the CCSS branch. Off the top of my head, the big differences between what is
implemented and what is in the document are as follows:
1. We did not end up modifying the Hangup application at all.
2. The document states that a single call completion monitor may be used across
   multiple calls to the same device. This proved to not be such a good idea
   when implementing protocol-specific monitors, and so we ended up using one
   monitor per-device per-call.
3. There are some configuration options which were conceived after the document
   was written. These are documented in the ccss.conf.sample that is on this
   review request.
		      
For some basic understanding of terminology used throughout this code, see the
ccss.tex document that is on this review.
This implements CCBS and CCNR in several flavors.
First up is a "generic" implementation, which can work over any channel technology
provided that the channel technology can accurately report device state. Call
completion is requested using the dialplan application CallCompletionRequest and can
be canceled using CallCompletionCancel. Device state subscriptions are used in order
to monitor the state of called parties.
Next, there is a SIP-specific implementation of call completion. This method uses the
methods outlined in draft-ietf-bliss-call-completion-06 to implement call completion
using SIP signaling. There are a few things to note here:
* The agent/monitor terminology used throughout Asterisk sometimes is the reverse of
  what is defined in the referenced draft.
* Implementation of the draft required support for SIP PUBLISH. I attempted to write
  this in a generic-enough fashion such that if someone were to want to write PUBLISH
  support for other event packages, such as dialog-state or presence, most of the effort
  would be in writing callbacks specific to the event package.
* A subportion of supporting PUBLISH reception was that we had to implement a PIDF
  parser. The PIDF support added is a bit minimal. I first wrote a validation
  routine to ensure that the PIDF document is formatted properly. The rest of the
  PIDF reading is done in-line in the call-completion-specific PUBLISH-handling
  code. In other words, while there is PIDF support here, it is not in any state
  where it could easily be applied to other event packages as is.
Finally, there are a variety of ISDN-related call completion protocols supported. These
were written by Richard Mudgett, and as such I can't really say much about their
implementation. There are notes in the CHANGES file that indicate the ISDN protocols
over which call completion is supported.
Review: https://reviewboard.asterisk.org/r/523
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-04-09 15:31:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														analog_get_orig_dialstring ( p ) ,  AST_CC_CCNR ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_queue_control ( p - > subs [ idx ] . owner ,  AST_CONTROL_RINGING ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXSLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXSKS : 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p - > answeronpolarityswitch  | |  p - > hanguponpolarityswitch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Ignore possible polarity reversal on line seizure \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > polaritydelaytv  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* fall through */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_EMWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_EM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_EM_E1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_E911 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FGC_CAMA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FGC_CAMAMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SFWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SF_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SF_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FEATDMF_TA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SF_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c  =  strchr ( dest ,  ' / ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( c )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											c + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											c  =  " " ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( strlen ( c )  <  p - > stripmsd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Number '%s' is shorter than stripmsd (%d) \n " ,  c ,  p - > stripmsd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  analog_start ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( errno  ! =  EINPROGRESS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Dialing '%s' \n " ,  c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										p - > dop . op  =  ANALOG_DIAL_OP_REPLACE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c  + =  p - > stripmsd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( mysig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATD : 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											l  =  ast_channel_connected ( ast ) - > id . number . valid  ?  ast_channel_connected ( ast ) - > id . number . str  :  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( l )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												snprintf ( p - > dop . dialstr ,  sizeof ( p - > dop . dialstr ) ,  " T*%s*%s* " ,  l ,  c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												snprintf ( p - > dop . dialstr ,  sizeof ( p - > dop . dialstr ) ,  " T**%s* " ,  c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATDMF : 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											l  =  ast_channel_connected ( ast ) - > id . number . valid  ?  ast_channel_connected ( ast ) - > id . number . str  :  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( l )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												snprintf ( p - > dop . dialstr ,  sizeof ( p - > dop . dialstr ) ,  " M*00%s#*%s# " ,  l ,  c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												snprintf ( p - > dop . dialstr ,  sizeof ( p - > dop . dialstr ) ,  " M*02#*%s# " ,  c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATDMF_TA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											const  char  * cic  =  " " ,  * ozz  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* If you have to go through a Tandem Access point you need to use this */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifndef STANDALONE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ozz  =  pbx_builtin_getvar_helper ( p - > owner ,  " FEATDMF_OZZ " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! ozz )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ozz  =  analog_defaultozz ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											cic  =  pbx_builtin_getvar_helper ( p - > owner ,  " FEATDMF_CIC " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! cic )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												cic  =  analog_defaultcic ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ozz  | |  ! cic )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Unable to dial channel of type feature group D MF tandem access without CIC or OZZ set \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											snprintf ( p - > dop . dialstr ,  sizeof ( p - > dop . dialstr ) ,  " M*%s%s# " ,  ozz ,  cic ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											snprintf ( p - > finaldial ,  sizeof ( p - > finaldial ) ,  " M*%s# " ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > whichwink  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_E911 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( p - > dop . dialstr ,  " M*911# " ,  sizeof ( p - > dop . dialstr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FGC_CAMA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											snprintf ( p - > dop . dialstr ,  sizeof ( p - > dop . dialstr ) ,  " P%s " ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FGC_CAMAMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											snprintf ( p - > dop . dialstr ,  sizeof ( p - > dop . dialstr ) ,  " M*%s# " ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( p - > pulse )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												snprintf ( p - > dop . dialstr ,  sizeof ( p - > dop . dialstr ) ,  " P%sw " ,  c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												snprintf ( p - > dop . dialstr ,  sizeof ( p - > dop . dialstr ) ,  " T%sw " ,  c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p - > echotraining  & &  ( strlen ( p - > dop . dialstr )  >  4 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											memset ( p - > echorest ,  ' w ' ,  sizeof ( p - > echorest )  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											strcpy ( p - > echorest  +  ( p - > echotraining  /  400 )  +  1 ,  p - > dop . dialstr  +  strlen ( p - > dop . dialstr )  -  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > echorest [ sizeof ( p - > echorest )  -  1 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > echobreak  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > dop . dialstr [ strlen ( p - > dop . dialstr ) - 2 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											p - > echobreak  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 22:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_waitingfordt ( p ,  ast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( ! res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( analog_dial_digits ( p ,  ANALOG_SUB_REAL ,  & p - > dop ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_on_hook ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Deferring dialing... \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 22:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_dialing ( p ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_strlen_zero ( c ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											p - > dialednone  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_setstate ( ast ,  AST_STATE_DIALING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " not yet implemented \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  analog_hangup ( struct  analog_pvt  * p ,  struct  ast_channel  * ast )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  idx ,  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " %s %d \n " ,  __FUNCTION__ ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ast_channel_tech_pvt ( ast ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Asked to hangup channel not connected \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									idx  =  analog_get_index ( ast ,  p ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									x  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p - > origcid_num )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( p - > cid_num ,  p - > origcid_num ,  sizeof ( p - > cid_num ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_free ( p - > origcid_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										p - > origcid_num  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( p - > origcid_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( p - > cid_name ,  p - > origcid_name ,  sizeof ( p - > cid_name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_free ( p - > origcid_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										p - > origcid_name  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									analog_dsp_set_digitmode ( p ,  ANALOG_DIGITMODE_DTMF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Hangup: channel: %d index = %d, normal = %d, callwait = %d, thirdcall = %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p - > channel ,  idx ,  p - > subs [ ANALOG_SUB_REAL ] . allocd ,  p - > subs [ ANALOG_SUB_CALLWAIT ] . allocd ,  p - > subs [ ANALOG_SUB_THREEWAY ] . allocd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( idx  >  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Real channel, do some fixup */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p - > subs [ idx ] . owner  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										p - > polarity  =  POLARITY_IDLE ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_linear_mode ( p ,  idx ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( idx )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  ANALOG_SUB_REAL : 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( p - > subs [ ANALOG_SUB_CALLWAIT ] . allocd  & &  p - > subs [ ANALOG_SUB_THREEWAY ] . allocd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Normal call hung up with both three way call and a call waiting call in place? \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( p - > subs [ ANALOG_SUB_CALLWAIT ] . inthreeway )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* We had flipped over to answer a callwait and now it's gone */ 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-30 21:04:31 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " We were flipped over to the callwait, moving back and not owning. \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													/* Move to the call-wait, but un-own us until they flip back. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_swap_subs ( p ,  ANALOG_SUB_CALLWAIT ,  ANALOG_SUB_REAL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_unalloc_sub ( p ,  ANALOG_SUB_CALLWAIT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_set_new_owner ( p ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* The three way hung up, but we still have a call wait */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " We were in the threeway and have a callwait still.  Ditching the threeway. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_swap_subs ( p ,  ANALOG_SUB_THREEWAY ,  ANALOG_SUB_REAL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_unalloc_sub ( p ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( p - > subs [ ANALOG_SUB_REAL ] . inthreeway )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/* This was part of a three way call.  Immediately make way for
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														   another  call  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " Call was complete, setting owner to former third call \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-01 17:32:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														analog_set_inthreeway ( p ,  ANALOG_SUB_REAL ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														analog_set_new_owner ( p ,  p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/* This call hasn't been completed yet...  Set owner to NULL */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " Call was incomplete, setting owner to NULL \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														analog_set_new_owner ( p ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( p - > subs [ ANALOG_SUB_CALLWAIT ] . allocd )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Need to hold the lock for real-call, private, and call-waiting call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_lock_sub_owner ( p ,  ANALOG_SUB_CALLWAIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! p - > subs [ ANALOG_SUB_CALLWAIT ] . owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* The call waiting call dissappeared. */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_set_new_owner ( p ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												/* Move to the call-wait and switch back to them. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_swap_subs ( p ,  ANALOG_SUB_CALLWAIT ,  ANALOG_SUB_REAL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_unalloc_sub ( p ,  ANALOG_SUB_CALLWAIT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_set_new_owner ( p ,  p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ast_channel_state ( p - > owner )  ! =  AST_STATE_UP )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_queue_control ( p - > subs [ ANALOG_SUB_REAL ] . owner ,  AST_CONTROL_ANSWER ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 21:21:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_queue_unhold ( p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Unlock the call-waiting call that we swapped to real-call. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_unlock ( p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  if  ( p - > subs [ ANALOG_SUB_THREEWAY ] . allocd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_swap_subs ( p ,  ANALOG_SUB_THREEWAY ,  ANALOG_SUB_REAL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_unalloc_sub ( p ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( p - > subs [ ANALOG_SUB_REAL ] . inthreeway )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* This was part of a three way call.  Immediately make way for
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   another  call  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Call was complete, setting owner to former third call \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-01 17:32:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_set_inthreeway ( p ,  ANALOG_SUB_REAL ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_set_new_owner ( p ,  p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* This call hasn't been completed yet...  Set owner to NULL */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Call was incomplete, setting owner to NULL \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_set_new_owner ( p ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SUB_CALLWAIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Ditch the holding callwait call, and immediately make it available */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( p - > subs [ ANALOG_SUB_CALLWAIT ] . inthreeway )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Need to hold the lock for call-waiting call, private, and 3-way call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_lock_sub_owner ( p ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												/* This is actually part of a three way, placed on hold.  Place the third part
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   on  music  on  hold  now  */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-01 20:00:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 21:21:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_queue_hold ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ,  p - > mohsuggest ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-01 17:32:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_set_inthreeway ( p ,  ANALOG_SUB_THREEWAY ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												/* Make it the call wait now */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_swap_subs ( p ,  ANALOG_SUB_CALLWAIT ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_unalloc_sub ( p ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( p - > subs [ ANALOG_SUB_CALLWAIT ] . owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Unlock the 3-way call that we swapped to call-waiting call. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_channel_unlock ( p - > subs [ ANALOG_SUB_CALLWAIT ] . owner ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												analog_unalloc_sub ( p ,  ANALOG_SUB_CALLWAIT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SUB_THREEWAY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Need to hold the lock for 3-way call, private, and call-waiting call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_lock_sub_owner ( p ,  ANALOG_SUB_CALLWAIT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( p - > subs [ ANALOG_SUB_CALLWAIT ] . inthreeway )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* The other party of the three way call is currently in a call-wait state.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   Start  music  on  hold  for  them ,  and  take  the  main  guy  out  of  the  third  call  */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-01 17:32:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_set_inthreeway ( p ,  ANALOG_SUB_CALLWAIT ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-01 20:00:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( p - > subs [ ANALOG_SUB_CALLWAIT ] . owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 21:21:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_queue_hold ( p - > subs [ ANALOG_SUB_CALLWAIT ] . owner ,  p - > mohsuggest ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p - > subs [ ANALOG_SUB_CALLWAIT ] . owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_unlock ( p - > subs [ ANALOG_SUB_CALLWAIT ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-01 17:32:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_set_inthreeway ( p ,  ANALOG_SUB_REAL ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											/* If this was part of a three way call index, let us make
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   another  three  way  call  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_unalloc_sub ( p ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  Should  never  happen . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  This  wasn ' t  any  sort  of  call ,  so  how  are  we  an  index ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " Index found but not any type of call? \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! p - > subs [ ANALOG_SUB_REAL ] . owner  & &  ! p - > subs [ ANALOG_SUB_CALLWAIT ] . owner  & &  ! p - > subs [ ANALOG_SUB_THREEWAY ] . owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_new_owner ( p ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-12 20:47:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_ringtimeout ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 22:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_confirmanswer ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_pulsedial ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-18 08:02:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_outgoing ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p - > onhooktime  =  time ( NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p - > cidrings  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Perform low level hangup if no owner left */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  analog_on_hook ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Unable to hangup line %s \n " ,  ast_channel_name ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( p - > sig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOKS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* If they're off hook, try playing congestion */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( analog_is_off_hook ( p ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 23:14:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_hangup_polarityswitch ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												analog_play_tone ( p ,  ANALOG_SUB_REAL ,  ANALOG_TONE_CONGESTION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												analog_play_tone ( p ,  ANALOG_SUB_REAL ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSKS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Make sure we're not made available for at least two seconds assuming
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   we  were  actually  used  for  an  inbound  or  outbound  call .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ast_channel_state ( ast )  ! =  AST_STATE_RESERVED )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												time ( & p - > guardtime ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > guardtime  + =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_play_tone ( p ,  ANALOG_SUB_REAL ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_set_echocanceller ( p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										x  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_setoption ( ast , AST_OPTION_TONE_VERIFY , & x , sizeof ( char ) , 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_setoption ( ast , AST_OPTION_TDD , & x , sizeof ( char ) , 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p - > callwaitcas  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_callwaiting ( p ,  p - > permcallwaiting ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												chan_dahdi: Fix broken hidecallerid setting.
The hidecallerid setting in chan_dahdi.conf currently
is broken for a couple reasons.
First, the actual code in sig_analog to "allow" or "block"
Caller ID depending on this setting improperly used
ast_set_callerid instead of updating the presentation.
This issue was mostly fixed in ASTERISK_29991, and that
fix is carried forward to this code as well.
Secondly, the hidecallerid setting is set on the DAHDI
pvt but not carried forward to the analog pvt properly.
This is because the chan_dahdi config loading code improperly
set permhidecallerid to permhidecallerid from the config file,
even though hidecallerid is what is actually set from the config
file. (This is done correctly for call waiting, a few lines above.)
This is fixed to read the proper value.
Thirdly, in sig_analog, hidecallerid is set to permhidecallerid
only on hangup. This can lead to potential security vulnerabilities
as an allowed Caller ID from an initial call can "leak" into subsequent
calls if no hangup occurs between them. This is fixed by setting
hidecallerid to permcallerid when calls begin, rather than when they end.
This also means we don't need to also set hidecallerid in chan_dahdi.c
when copying from the config, as we would have to otherwise.
Fourthly, sig_analog currently only allows dialing *67 or *82 if
that would actually toggle the presentation. A comment is added
clarifying that this behavior is okay.
Finally, a couple log messages are updated to be more accurate.
Resolves: #100
ASTERISK-30349 #close
(cherry picked from commit d496544d7bb0d1b839ae581d9ef2b46cbf1bf9cd)
											 
										 
										
											2023-05-18 17:37:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* In theory, the below is not necessary since we set hidecallerid = permhidecaller when calls start,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  but  this  ensures  the  setting  is  defaulted  properly  when  channels  are  idle ,  too .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										p - > hidecallerid  =  p - > permhidecallerid ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 22:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_dialing ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										analog_update_conf ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_all_subchannels_hungup ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									analog_stop_callwait ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_verb ( 3 ,  " Hanging up on '%s' \n " ,  ast_channel_name ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  analog_answer ( struct  analog_pvt  * p ,  struct  ast_channel  * ast )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  idx ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  oldstate  =  ast_channel_state ( ast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " %s %d \n " ,  __FUNCTION__ ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									ast_setstate ( ast ,  AST_STATE_UP ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									idx  =  analog_get_index ( ast ,  p ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( idx  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										idx  =  ANALOG_SUB_REAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									switch  ( p - > sig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXSLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXSKS : 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-12 20:47:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_ringtimeout ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_EM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_EM_E1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_EMWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FEATDMF_TA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_E911 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FGC_CAMA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FGC_CAMAMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SFWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SF_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SF_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SF_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXOLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXOGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXOKS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Pick up the line */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Took %s off hook \n " ,  ast_channel_name ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( p - > hanguponpolarityswitch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											gettimeofday ( & p - > polaritydelaytv ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  analog_off_hook ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_play_tone ( p ,  idx ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 22:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_dialing ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( idx  = =  ANALOG_SUB_REAL )  & &  p - > subs [ ANALOG_SUB_THREEWAY ] . inthreeway )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( oldstate  = =  AST_STATE_RINGING )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Finally swapping real and threeway \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_play_tone ( p ,  ANALOG_SUB_THREEWAY ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_swap_subs ( p ,  ANALOG_SUB_THREEWAY ,  ANALOG_SUB_REAL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_set_new_owner ( p ,  p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 23:14:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( p - > sig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSKS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											analog_set_echocanceller ( p ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_train_echocanceller ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 23:14:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOKS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_answer_polarityswitch ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Don't know how to answer signalling %d (channel %d) \n " ,  p - > sig ,  p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_setstate ( ast ,  AST_STATE_UP ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_handles_digit ( struct  ast_frame  * f )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  subclass  =  toupper ( f - > subclass . integer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( subclass )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 1 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 2 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 3 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 4 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 5 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 6 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 7 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' 9 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' A ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' B ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' C ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' D ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' E ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ' F ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  analog_handle_dtmf ( struct  analog_pvt  * p ,  struct  ast_channel  * ast ,  enum  analog_sub  idx ,  struct  ast_frame  * * dest )  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  * f  =  * dest ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " %s DTMF digit: 0x%02X '%c' on %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										f - > frametype  = =  AST_FRAME_DTMF_BEGIN  ?  " Begin "  :  " End " , 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										( unsigned ) f - > subclass . integer ,  f - > subclass . integer ,  ast_channel_name ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 22:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_check_confirmanswer ( p ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( f - > frametype  = =  AST_FRAME_DTMF_END )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Confirm answer on %s! \n " ,  ast_channel_name ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Upon receiving a DTMF digit, consider this an answer confirmation instead
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											of  a  DTMF  digit  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > subs [ idx ] . f . frametype  =  AST_FRAME_CONTROL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > subs [ idx ] . f . subclass . integer  =  AST_CONTROL_ANSWER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Reset confirmanswer so DTMF's will behave properly for the duration of the call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_set_confirmanswer ( p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > subs [ idx ] . f . frametype  =  AST_FRAME_NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > subs [ idx ] . f . subclass . integer  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										* dest  =  & p - > subs [ idx ] . f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( p - > callwaitcas )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( f - > frametype  = =  AST_FRAME_DTMF_END )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( f - > subclass . integer  = =  ' A ' )  | |  ( f - > subclass . integer  = =  ' D ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Got some DTMF, but it's for the CAS \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > caller . id . name . str  =  p - > callwait_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > caller . id . number . str  =  p - > callwait_num ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_send_callerid ( p ,  1 ,  & p - > caller ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( analog_handles_digit ( f ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > callwaitcas  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p - > subs [ idx ] . f . frametype  =  AST_FRAME_NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p - > subs [ idx ] . f . subclass . integer  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* dest  =  & p - > subs [ idx ] . f ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_cb_handle_dtmf ( p ,  ast ,  idx ,  dest ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_my_getsigstr ( struct  ast_channel  * chan ,  char  * str ,  const  char  * term ,  int  ms )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									* str  =  0 ;  /* start with empty output buffer */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Wait for the first digit (up to specified ms). */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										c  =  ast_waitfordigit ( chan ,  ms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* if timeout, hangup or error, return as such */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( c  <  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  c ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										* str + +  =  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* str  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( strchr ( term ,  c ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_handle_notify_message ( struct  ast_channel  * chan ,  struct  analog_pvt  * p ,  int  cid_flags ,  int  neon_mwievent )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . handle_notify_message )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . handle_notify_message ( chan ,  p - > chan_pvt ,  cid_flags ,  neon_mwievent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_increase_ss_count ( void )  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . increase_ss_count )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . increase_ss_count ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_decrease_ss_count ( void )  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . decrease_ss_count )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . decrease_ss_count ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  analog_distinctive_ring ( struct  ast_channel  * chan ,  struct  analog_pvt  * p ,  int  idx ,  int  * ringdata )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! p - > usedistinctiveringdetection )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . distinctive_ring )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . distinctive_ring ( chan ,  p - > chan_pvt ,  idx ,  ringdata ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  analog_get_and_handle_alarms ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . get_and_handle_alarms )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_callbacks . get_and_handle_alarms ( p - > chan_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  * analog_get_bridged_channel ( struct  ast_channel  * chan )  
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . get_sigpvt_bridged_channel )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . get_sigpvt_bridged_channel ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  analog_get_sub_fd ( struct  analog_pvt  * p ,  enum  analog_sub  sub )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( analog_callbacks . get_sub_fd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  analog_callbacks . get_sub_fd ( p - > chan_pvt ,  sub ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# define ANALOG_NEED_MFDETECT(p) (((p)->sig == ANALOG_SIG_FEATDMF) || ((p)->sig == ANALOG_SIG_FEATDMF_TA) || ((p)->sig == ANALOG_SIG_E911) || ((p)->sig == ANALOG_SIG_FGC_CAMA) || ((p)->sig == ANALOG_SIG_FGC_CAMAMF) || ((p)->sig == ANALOG_SIG_FEATB)) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-06-06 21:40:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  analog_canmatch_featurecode ( const  char  * pickupexten ,  const  char  * exten )  
						 
					
						
							
								
									
										
										
										
											2011-08-03 13:40:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  extlen  =  strlen ( exten ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! extlen )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-06 21:40:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( extlen  <  strlen ( pickupexten )  & &  ! strncmp ( pickupexten ,  exten ,  extlen ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-03 13:40:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* hardcoded features are *60, *67, *69, *70, *72, *73, *78, *79, *82, *0 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( exten [ 0 ]  = =  ' * '  & &  extlen  <  3 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( extlen  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* "*0" should be processed before it gets here */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( exten [ 1 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ' 6 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ' 7 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ' 8 ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  void  * __analog_ss_thread ( void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  analog_pvt  * p  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan  =  p - > ss_astchan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  exten [ AST_MAX_EXTENSION ]  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  exten2 [ AST_MAX_EXTENSION ]  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  dtmfcid [ 300 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  dtmfbuf [ 300 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  namebuf [ ANALOG_MAX_CID ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  numbuf [ ANALOG_MAX_CID ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * name  =  NULL ,  * number  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-17 15:42:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  flags  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_smdi_md_message  * smdi_msg  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  timeout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  getforward  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * s1 ,  * s2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  idx ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-13 01:12:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_callid  callid ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-06 21:40:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									RAII_VAR ( struct  ast_features_pickup_config  * ,  pickup_cfg ,  NULL ,  ao2_cleanup ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * pickupexten ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									analog_increase_ss_count ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " %s %d \n " ,  __FUNCTION__ ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-06 20:15:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* What happened to the channel? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( callid  =  ast_channel_callid ( chan ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_callid_threadassoc_add ( callid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* in the bizarre case where the channel has become a zombie before we
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   even  get  started  here ,  abort  safely 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									*/ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ast_channel_tech_pvt ( chan ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Channel became a zombie before simple switch could be started (%s) \n " ,  ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_verb ( 3 ,  " Starting simple switch on '%s' \n " ,  ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									idx  =  analog_get_index ( chan ,  p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( idx  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-06 21:40:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pickup_cfg  =  ast_get_chan_features_pickup_config ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! pickup_cfg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Unable to retrieve pickup configuration options. Unable to detect call pickup extension \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pickupexten  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pickupexten  =  ast_strdupa ( pickup_cfg - > pickupexten ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									analog_dsp_reset_and_flush_digits ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( p - > sig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FEATDMF_TA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_E911 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FGC_CAMAMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_EMWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SF_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SF_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SF_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SFWINK : 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( analog_wink ( p ,  idx ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_EM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_EM_E1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_SF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FGC_CAMA : 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										res  =  analog_play_tone ( p ,  idx ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_dsp_reset_and_flush_digits ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* set digit mode appropriately */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( ANALOG_NEED_MFDETECT ( p ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_dsp_set_digitmode ( p ,  ANALOG_DIGITMODE_MF ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											analog_dsp_set_digitmode ( p ,  ANALOG_DIGITMODE_DTMF ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memset ( dtmfbuf ,  0 ,  sizeof ( dtmfbuf ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Wait for the first digit only if immediate=no */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! p - > immediate )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											/* Wait for the first digit (up to 5 seconds). */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  ast_waitfordigit ( chan ,  5000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( res  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* save first char */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											dtmfbuf [ 0 ]  =  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch  ( p - > sig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ANALOG_SIG_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ANALOG_SIG_SF_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  analog_my_getsigstr ( chan ,  dtmfbuf  +  1 ,  " * " ,  3000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( res  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													res  =  analog_my_getsigstr ( chan ,  dtmfbuf  +  strlen ( dtmfbuf ) ,  " * " ,  3000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( res  <  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													analog_dsp_reset_and_flush_digits ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ANALOG_SIG_FEATDMF_TA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  analog_my_getsigstr ( chan ,  dtmfbuf  +  1 ,  " # " ,  3000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( res  <  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													analog_dsp_reset_and_flush_digits ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( analog_wink ( p ,  idx ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												dtmfbuf [ 0 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Wait for the first digit (up to 5 seconds). */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  ast_waitfordigit ( chan ,  5000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( res  < =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												dtmfbuf [ 0 ]  =  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* fall through intentionally */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ANALOG_SIG_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ANALOG_SIG_E911 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ANALOG_SIG_FGC_CAMAMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ANALOG_SIG_SF_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  analog_my_getsigstr ( chan ,  dtmfbuf  +  1 ,  " # " ,  3000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* if international caca, do it again to get real ANO */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-25 04:06:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ( p - > sig  = =  ANALOG_SIG_FEATDMF )  & &  ( dtmfbuf [ 1 ]  ! =  ' 0 ' ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													& &  ( strlen ( dtmfbuf )  ! =  14 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( analog_wink ( p ,  idx ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													dtmfbuf [ 0 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Wait for the first digit (up to 5 seconds). */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  ast_waitfordigit ( chan ,  5000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( res  < =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													dtmfbuf [ 0 ]  =  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  analog_my_getsigstr ( chan ,  dtmfbuf  +  1 ,  " # " ,  3000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( res  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* if E911, take off hook */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( p - > sig  = =  ANALOG_SIG_E911 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														analog_off_hook ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( res  <  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													analog_dsp_reset_and_flush_digits ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ANALOG_SIG_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ANALOG_SIG_SF_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  analog_my_getsigstr ( chan ,  dtmfbuf  +  1 ,  " # " ,  3000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( res  <  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													analog_dsp_reset_and_flush_digits ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  ANALOG_SIG_EMWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* if we received a '*', we are actually receiving Feature Group D
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   dial  syntax ,  so  use  that  mode ;  otherwise ,  fall  through  to  normal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   mode 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( res  = =  ' * ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  analog_my_getsigstr ( chan ,  dtmfbuf  +  1 ,  " * " ,  3000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( res  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														res  =  analog_my_getsigstr ( chan ,  dtmfbuf  +  strlen ( dtmfbuf ) ,  " * " ,  3000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( res  <  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														analog_dsp_reset_and_flush_digits ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* If we got the first digit, get the rest */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												len  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												dtmfbuf [ len ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												while  ( ( len  <  AST_MAX_EXTENSION - 1 )  & &  ast_matchmore_extension ( chan ,  ast_channel_context ( chan ) ,  dtmfbuf ,  1 ,  p - > cid_num ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( ast_exists_extension ( chan ,  ast_channel_context ( chan ) ,  dtmfbuf ,  1 ,  p - > cid_num ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-21 14:30:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														timeout  =  analog_get_matchdigit_timeout ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-21 14:30:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														timeout  =  analog_get_interdigit_timeout ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  ast_waitfordigit ( chan ,  timeout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " waitfordigit returned < 0... \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														dtmfbuf [ len + + ]  =  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														dtmfbuf [ len ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " getdtmf on channel %d: %s \n " ,  p - > channel ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Got hung up before digits finished \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 21:36:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p - > sig  = =  ANALOG_SIG_FGC_CAMA  | |  p - > sig  = =  ANALOG_SIG_FGC_CAMAMF )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* This if block is where we process ANI for CAMA */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											char  anibuf [ 100 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 21:36:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											struct  ast_party_caller  * caller ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* cnoffset is the point at which we pull the calling number out
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  of  anibuf .  Must  be  the  number  of  ani_info_digits  +  1  to  account 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  for  the  KP ,  which  is  considered  a  digit .   */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* The 1XB with ANI-B will send a full 10 digits
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											*   or  2  digits  in  case  of  ANI  failure . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											*  ( CD - 95811 - 01  Section  II ,  page  10 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											*  10  digit  string  example :   * 08320123 # 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											*  2  digit  string  example :    * 2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											*  KP  ( * )  and  ST  ( # )  are  considered  to  be  digits  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 21:36:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int  cnoffset  =  p - > ani_info_digits  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " cnoffset: %d \n " ,  cnoffset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* This is how long to wait before the wink to start ANI spill
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  Pulled  from  chan_dahdi . conf ,  default  is  1000 ms  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_safe_sleep ( chan , p - > ani_wink_time )  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  quit ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_off_hook ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 21:36:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Sent wink to signal ANI start \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											analog_dsp_set_digitmode ( p ,  ANALOG_DIGITMODE_MF ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 21:36:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* ani_timeout is configured in chan_dahdi.conf. default is 10000ms.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  ST ,  STP ,  ST2P ,  ST3P  can  all  signal  transmission  complete ,  regardless  of  timeout  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  analog_my_getsigstr ( chan ,  anibuf ,  " #ABC " ,  p - > ani_timeout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* so we can work with the ani buffer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pbx_builtin_setvar_helper ( chan ,  " ANIBUF " ,  anibuf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* as long as we get a terminating pulse OR the length of ANI buffer is at least >=2, we can treat
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  this  as  a  complete  spill  for  the  purposes  of  setting  anistart  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( res  >  0 )  | |  ( strlen ( anibuf )  > =  2 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												char  anistart [ 2 ]  =  " X " ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-24 11:55:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												char  f [ 101 ]  =  { 0 } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 21:36:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( strchr ( " #ABC " ,  anibuf [ strlen ( anibuf )  -  1 ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													anistart [ 0 ]  =  anibuf [ strlen ( anibuf )  -  1 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													anibuf [ strlen ( anibuf )  -  1 ]  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 21:36:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_set_callerid ( chan ,  anibuf  +  cnoffset ,  NULL ,  anibuf  +  cnoffset ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												caller  =  ast_channel_caller ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												strncpy ( f ,  & ( anibuf [ 1 ] ) ,  MIN ( ( int ) ( p - > ani_info_digits ) ,  sizeof ( f ) - 1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												caller - > ani2  =  atoi ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												anibuf [ cnoffset ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* so we can work with the different start pulses as used in ANI-D */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pbx_builtin_setvar_helper ( chan ,  " ANISTART " ,  anistart ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* so we can use our ANI INFO digits in our dialplan */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pbx_builtin_setvar_helper ( chan ,  " ANI2 " ,  anibuf  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_dsp_set_digitmode ( p ,  ANALOG_DIGITMODE_DTMF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( exten ,  dtmfbuf ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_strlen_zero ( exten ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( exten ,  " s " ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( p - > sig  = =  ANALOG_SIG_FEATD  | |  p - > sig  = =  ANALOG_SIG_EMWINK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Look for Feature Group D on all E&M Wink and Feature Group D trunks */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( exten [ 0 ]  = =  ' * ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												char  * stringp = NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_copy_string ( exten2 ,  exten ,  sizeof ( exten2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Parse out extension and callerid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												stringp = exten2  + 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s1  =  strsep ( & stringp ,  " * " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s2  =  strsep ( & stringp ,  " * " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( s2 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! ast_strlen_zero ( p - > cid_num ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_set_callerid ( chan ,  p - > cid_num ,  NULL ,  p - > cid_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_set_callerid ( chan ,  s1 ,  NULL ,  s1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_copy_string ( exten ,  s2 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_copy_string ( exten ,  s1 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( p - > sig  = =  ANALOG_SIG_FEATD )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( p - > sig  = =  ANALOG_SIG_FEATDMF )  | |  ( p - > sig  = =  ANALOG_SIG_FEATDMF_TA ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( exten [ 0 ]  = =  ' * ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												char  * stringp = NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-18 20:09:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												struct  ast_party_caller  * caller ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_copy_string ( exten2 ,  exten ,  sizeof ( exten2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Parse out extension and callerid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												stringp = exten2  + 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s1  =  strsep ( & stringp ,  " # " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s2  =  strsep ( & stringp ,  " # " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( s2 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! ast_strlen_zero ( p - > cid_num ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_set_callerid ( chan ,  p - > cid_num ,  NULL ,  p - > cid_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( * ( s1  +  2 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															ast_set_callerid ( chan ,  s1  +  2 ,  NULL ,  s1  +  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_copy_string ( exten ,  s2  +  1 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_copy_string ( exten ,  s1  +  2 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2014-12-18 20:09:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* The first two digits are ani2 information. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												caller  =  ast_channel_caller ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s1 [ 2 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												caller - > ani2  =  atoi ( s1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Got a non-Feature Group D input on channel %d.  Assuming E&M Wink instead \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( p - > sig  = =  ANALOG_SIG_E911 )  | |  ( p - > sig  = =  ANALOG_SIG_FGC_CAMAMF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( exten [ 0 ]  = =  ' * ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												char  * stringp = NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_copy_string ( exten2 ,  exten ,  sizeof ( exten2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Parse out extension and callerid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												stringp = exten2  + 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s1  =  strsep ( & stringp ,  " # " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s2  =  strsep ( & stringp ,  " # " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( s2  & &  ( * ( s2  +  1 )  = =  ' 0 ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( * ( s2  +  2 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_set_callerid ( chan ,  s2  +  2 ,  NULL ,  s2  +  2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( s1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_copy_string ( exten ,  s1 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_copy_string ( exten ,  " 911 " ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 21:36:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " A KP was expected to start signaling for Feature Group C CAMA-MF, but we got something else. Received: %s on channel %d \n " ,  exten ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p - > sig  = =  ANALOG_SIG_FEATB )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( exten [ 0 ]  = =  ' * ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												char  * stringp = NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_copy_string ( exten2 ,  exten ,  sizeof ( exten2 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Parse out extension and callerid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												stringp = exten2  + 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												s1  =  strsep ( & stringp ,  " # " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_copy_string ( exten ,  exten2  +  1 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-19 21:36:34 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " A KP was expected to start signaling for Feature Group B, but we got something else. Received: %s on channel %d \n " ,  exten ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( p - > sig  = =  ANALOG_SIG_FEATDMF )  | |  ( p - > sig  = =  ANALOG_SIG_FEATDMF_TA ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_wink ( p ,  idx ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-11 15:47:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  Some  switches  require  a  minimum  guard  time  between  the  last 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  FGD  wink  and  something  that  answers  immediately .   This 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  ensures  it . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_safe_sleep ( chan ,  100 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_set_echocanceller ( p ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_dsp_set_digitmode ( p ,  ANALOG_DIGITMODE_DTMF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_exists_extension ( chan ,  ast_channel_context ( chan ) ,  exten ,  1 , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_channel_caller ( chan ) - > id . number . valid  ?  ast_channel_caller ( chan ) - > id . number . str  :  NULL ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_channel_exten_set ( chan ,  exten ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											analog_dsp_reset_and_flush_digits ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  ast_pbx_run ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " PBX exited non-zero \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_CONGESTION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_verb ( 3 ,  " Unknown extension '%s' in context '%s' requested \n " ,  exten ,  ast_channel_context ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											sleep ( 2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_INFO ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( res  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Unable to start special tone on %d \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												sleep ( 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-24 20:12:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  ast_streamfile ( chan ,  " ss-noservice " ,  ast_channel_language ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( res  > =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_waitstream ( chan ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_CONGESTION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXOLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXOGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXOKS : 
							 
						 
					
						
							
								
									
										
											 
										
											
												chan_dahdi: Fix broken hidecallerid setting.
The hidecallerid setting in chan_dahdi.conf currently
is broken for a couple reasons.
First, the actual code in sig_analog to "allow" or "block"
Caller ID depending on this setting improperly used
ast_set_callerid instead of updating the presentation.
This issue was mostly fixed in ASTERISK_29991, and that
fix is carried forward to this code as well.
Secondly, the hidecallerid setting is set on the DAHDI
pvt but not carried forward to the analog pvt properly.
This is because the chan_dahdi config loading code improperly
set permhidecallerid to permhidecallerid from the config file,
even though hidecallerid is what is actually set from the config
file. (This is done correctly for call waiting, a few lines above.)
This is fixed to read the proper value.
Thirdly, in sig_analog, hidecallerid is set to permhidecallerid
only on hangup. This can lead to potential security vulnerabilities
as an allowed Caller ID from an initial call can "leak" into subsequent
calls if no hangup occurs between them. This is fixed by setting
hidecallerid to permcallerid when calls begin, rather than when they end.
This also means we don't need to also set hidecallerid in chan_dahdi.c
when copying from the config, as we would have to otherwise.
Fourthly, sig_analog currently only allows dialing *67 or *82 if
that would actually toggle the presentation. A comment is added
clarifying that this behavior is okay.
Finally, a couple log messages are updated to be more accurate.
Resolves: #100
ASTERISK-30349 #close
(cherry picked from commit d496544d7bb0d1b839ae581d9ef2b46cbf1bf9cd)
											 
										 
										
											2023-05-18 17:37:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Set our default presentation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  This  is  necessary  because  the  presentation  for  each  call  is  independent 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  ( though  the  default  may  be  the  same ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  For  example ,  if  hidecallerid = yes  and  somebody  makes  a  call  with  * 82 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  then  makes  a  3 - way  call ,  the  presentation  for  the  2 nd  call  should  still 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  be  blocked ,  unless  that  also  had  a  * 82. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  For  this  reason ,  setting  hidecallerid  =  permhidecallerid  on  hangup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  is  NOT  sufficient ,  as  the  * 82  from  the  first  call  could  " leak "  into 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  subsequent  ones  made  before  a  hangup ,  improperly  leaking  a  number 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  that  should  have  been  hidden . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p - > hidecallerid  =  p - > permhidecallerid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Read the first digit */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-21 14:30:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										timeout  =  analog_get_firstdigit_timeout ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* If starting a threeway call, never timeout on the first digit so someone
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   can  use  flash - hook  as  a  " hold "  feature  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-01 11:54:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											timeout  =  INT_MAX ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										while  ( len  <  AST_MAX_EXTENSION - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-17 15:01:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int  is_exten_parking  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											/* Read digit unless it's supposed to be immediate, in which case the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   only  answer  is  ' s '  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( p - > immediate )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												res  =  ' s ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												res  =  ast_waitfordigit ( chan ,  timeout ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											timeout  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " waitfordigit returned < 0... \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												res  =  analog_play_tone ( p ,  idx ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  quit ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 , " waitfordigit returned '%c' (%d), timeout = %d \n " ,  res ,  res ,  timeout ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												exten [ len + + ] = res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												exten [ len ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! ast_ignore_pattern ( ast_channel_context ( chan ) ,  exten ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_play_tone ( p ,  idx ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_play_tone ( p ,  idx ,  ANALOG_TONE_DIALTONE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-17 15:01:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ast_parking_provider_registered ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												is_exten_parking  =  ast_parking_is_exten_park ( ast_channel_context ( chan ) ,  exten ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-01 20:55:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ast_exists_extension ( chan ,  ast_channel_context ( chan ) ,  exten ,  1 ,  p - > cid_num )  & &  ! is_exten_parking )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! res  | |  ! ast_matchmore_extension ( chan ,  ast_channel_context ( chan ) ,  exten ,  1 ,  p - > cid_num ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													if  ( getforward )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/* Record this as the forwarding extension */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 16:24:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_copy_string ( p - > call_forward ,  exten ,  sizeof ( p - > call_forward ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-25 19:54:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_verb ( 3 ,  " Setting call forward to '%s' on channel %d \n " ,  p - > call_forward ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_DIALRECALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														usleep ( 500000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														res  =  analog_play_tone ( p ,  idx ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														sleep ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														memset ( exten ,  0 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_DIALTONE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														getforward  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														res  =  analog_play_tone ( p ,  idx ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-18 20:33:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_channel_exten_set ( chan ,  exten ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												chan_dahdi: Fix broken hidecallerid setting.
The hidecallerid setting in chan_dahdi.conf currently
is broken for a couple reasons.
First, the actual code in sig_analog to "allow" or "block"
Caller ID depending on this setting improperly used
ast_set_callerid instead of updating the presentation.
This issue was mostly fixed in ASTERISK_29991, and that
fix is carried forward to this code as well.
Secondly, the hidecallerid setting is set on the DAHDI
pvt but not carried forward to the analog pvt properly.
This is because the chan_dahdi config loading code improperly
set permhidecallerid to permhidecallerid from the config file,
even though hidecallerid is what is actually set from the config
file. (This is done correctly for call waiting, a few lines above.)
This is fixed to read the proper value.
Thirdly, in sig_analog, hidecallerid is set to permhidecallerid
only on hangup. This can lead to potential security vulnerabilities
as an allowed Caller ID from an initial call can "leak" into subsequent
calls if no hangup occurs between them. This is fixed by setting
hidecallerid to permcallerid when calls begin, rather than when they end.
This also means we don't need to also set hidecallerid in chan_dahdi.c
when copying from the config, as we would have to otherwise.
Fourthly, sig_analog currently only allows dialing *67 or *82 if
that would actually toggle the presentation. A comment is added
clarifying that this behavior is okay.
Finally, a couple log messages are updated to be more accurate.
Resolves: #100
ASTERISK-30349 #close
(cherry picked from commit d496544d7bb0d1b839ae581d9ef2b46cbf1bf9cd)
											 
										 
										
											2023-05-18 17:37:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/* Properly set the presentation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 *  We  need  to  do  this  here  as  well ,  because  p - > hidecallerid  might  be  set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 *  due  to  permanent  blocking ,  not  star - 67 / star - 82  usage .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( p - > hidecallerid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_channel_caller ( chan ) - > id . number . presentation  =  AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_channel_caller ( chan ) - > id . name . presentation  =  AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_channel_caller ( chan ) - > id . number . presentation  =  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_channel_caller ( chan ) - > id . name . presentation  =  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
											 
										
											
												chan_dahdi: Fix broken hidecallerid setting.
The hidecallerid setting in chan_dahdi.conf currently
is broken for a couple reasons.
First, the actual code in sig_analog to "allow" or "block"
Caller ID depending on this setting improperly used
ast_set_callerid instead of updating the presentation.
This issue was mostly fixed in ASTERISK_29991, and that
fix is carried forward to this code as well.
Secondly, the hidecallerid setting is set on the DAHDI
pvt but not carried forward to the analog pvt properly.
This is because the chan_dahdi config loading code improperly
set permhidecallerid to permhidecallerid from the config file,
even though hidecallerid is what is actually set from the config
file. (This is done correctly for call waiting, a few lines above.)
This is fixed to read the proper value.
Thirdly, in sig_analog, hidecallerid is set to permhidecallerid
only on hangup. This can lead to potential security vulnerabilities
as an allowed Caller ID from an initial call can "leak" into subsequent
calls if no hangup occurs between them. This is fixed by setting
hidecallerid to permcallerid when calls begin, rather than when they end.
This also means we don't need to also set hidecallerid in chan_dahdi.c
when copying from the config, as we would have to otherwise.
Fourthly, sig_analog currently only allows dialing *67 or *82 if
that would actually toggle the presentation. A comment is added
clarifying that this behavior is okay.
Finally, a couple log messages are updated to be more accurate.
Resolves: #100
ASTERISK-30349 #close
(cherry picked from commit d496544d7bb0d1b839ae581d9ef2b46cbf1bf9cd)
											 
										 
										
											2023-05-18 17:37:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_setstate ( chan ,  AST_STATE_RING ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-18 20:33:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														analog_set_echocanceller ( p ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														res  =  ast_pbx_run ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_log ( LOG_WARNING ,  " PBX exited non-zero \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_CONGESTION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* It's a match, but they just typed a digit, and there is an ambiguous match,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   so  just  set  the  timeout  to  analog_matchdigittimeout  and  wait  some  more  */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-21 14:30:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													timeout  =  analog_get_matchdigit_timeout ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( res  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " not enough digits (and no ambiguous match)... \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_CONGESTION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												analog_wait_event ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( p - > callwaiting  & &  ! strcmp ( exten ,  " *70 " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_verb ( 3 ,  " Disabling call waiting on %s \n " ,  ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												/* Disable call waiting if enabled */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_set_callwaiting ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_DIALRECALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 16:24:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Unable to do dial recall on channel %s: %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_channel_name ( chan ) ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												memset ( exten ,  0 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-21 14:30:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												timeout  =  analog_get_firstdigit_timeout ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-06-06 21:40:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( ! strcmp ( exten ,  pickupexten ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												/* Scan all channels and see if there are any
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  ringing  channels  that  have  call  groups 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-01 00:49:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												 *  that  equal  this  channel ' s  pickup  group 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( idx  = =  ANALOG_SUB_REAL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													/* Switch us from Third call to Call Wait */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-01 00:49:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														/* If you make a threeway call and then *8# a call, it should actually
 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														   look  like  a  callwait  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_alloc_sub ( p ,  ANALOG_SUB_CALLWAIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_swap_subs ( p ,  ANALOG_SUB_CALLWAIT ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_unalloc_sub ( p ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_set_echocanceller ( p ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( ast_pickup_call ( chan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " No call pickup possible... \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_CONGESTION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														analog_wait_event ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Huh?  Got *8# on call not on real \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
											 
										
											
												chan_dahdi: Fix broken hidecallerid setting.
The hidecallerid setting in chan_dahdi.conf currently
is broken for a couple reasons.
First, the actual code in sig_analog to "allow" or "block"
Caller ID depending on this setting improperly used
ast_set_callerid instead of updating the presentation.
This issue was mostly fixed in ASTERISK_29991, and that
fix is carried forward to this code as well.
Secondly, the hidecallerid setting is set on the DAHDI
pvt but not carried forward to the analog pvt properly.
This is because the chan_dahdi config loading code improperly
set permhidecallerid to permhidecallerid from the config file,
even though hidecallerid is what is actually set from the config
file. (This is done correctly for call waiting, a few lines above.)
This is fixed to read the proper value.
Thirdly, in sig_analog, hidecallerid is set to permhidecallerid
only on hangup. This can lead to potential security vulnerabilities
as an allowed Caller ID from an initial call can "leak" into subsequent
calls if no hangup occurs between them. This is fixed by setting
hidecallerid to permcallerid when calls begin, rather than when they end.
This also means we don't need to also set hidecallerid in chan_dahdi.c
when copying from the config, as we would have to otherwise.
Fourthly, sig_analog currently only allows dialing *67 or *82 if
that would actually toggle the presentation. A comment is added
clarifying that this behavior is okay.
Finally, a couple log messages are updated to be more accurate.
Resolves: #100
ASTERISK-30349 #close
(cherry picked from commit d496544d7bb0d1b839ae581d9ef2b46cbf1bf9cd)
											 
										 
										
											2023-05-18 17:37:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* While the DMS-100 allows dialing as many *67s and *82s in succession as one's heart may desire,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  the  5 ESS  does  not ,  it  only  allows  pure  toggling  ( and  only  once ! ) .  So ,  it ' s  not  incorrect 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  to  prevent  people  from  dialing  * 67  if  that  won ' t  actually  do  anything .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  if  ( ! p - > hidecallerid  & &  ! strcmp ( exten ,  " *67 " ) )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												chan_dahdi: Fix broken hidecallerid setting.
The hidecallerid setting in chan_dahdi.conf currently
is broken for a couple reasons.
First, the actual code in sig_analog to "allow" or "block"
Caller ID depending on this setting improperly used
ast_set_callerid instead of updating the presentation.
This issue was mostly fixed in ASTERISK_29991, and that
fix is carried forward to this code as well.
Secondly, the hidecallerid setting is set on the DAHDI
pvt but not carried forward to the analog pvt properly.
This is because the chan_dahdi config loading code improperly
set permhidecallerid to permhidecallerid from the config file,
even though hidecallerid is what is actually set from the config
file. (This is done correctly for call waiting, a few lines above.)
This is fixed to read the proper value.
Thirdly, in sig_analog, hidecallerid is set to permhidecallerid
only on hangup. This can lead to potential security vulnerabilities
as an allowed Caller ID from an initial call can "leak" into subsequent
calls if no hangup occurs between them. This is fixed by setting
hidecallerid to permcallerid when calls begin, rather than when they end.
This also means we don't need to also set hidecallerid in chan_dahdi.c
when copying from the config, as we would have to otherwise.
Fourthly, sig_analog currently only allows dialing *67 or *82 if
that would actually toggle the presentation. A comment is added
clarifying that this behavior is okay.
Finally, a couple log messages are updated to be more accurate.
Resolves: #100
ASTERISK-30349 #close
(cherry picked from commit d496544d7bb0d1b839ae581d9ef2b46cbf1bf9cd)
											 
										 
										
											2023-05-18 17:37:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_verb ( 3 ,  " Blocking Caller*ID on %s \n " ,  ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												/* Disable Caller*ID if enabled */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > hidecallerid  =  1 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												chan_dahdi: Fix buggy and missing Caller ID parameters
There are several things wrong with analog Caller ID
handling that are fixed by this commit:
callerid.c's Caller ID generation function contains the
logic to use the presentation to properly send the proper
Caller ID. However, currently, DAHDI does not pass any
presentation information to the Caller ID module, which
means that presentation is completely ignored on all calls.
This means that lines could be getting Caller ID information
they aren't supposed to.
Part of the reason this has been obscured is because the
simple switch logic for handling the built in *67 and *82
is completely wrong. Rather than modifying the presentation
for the call accordingly (which is what it's supposed to do),
it simply blanks out the Caller ID or fills it in. This is
wrong, so wrong that it makes a mockery of the specification.
Additionally, it would leave to the "UNAVAILABLE" disposition
being used for Caller ID generation as opposed to the "PRIVATE"
disposition that it should have been using. This is now fixed
to only update the presentation and not modify the number and
name, so that the simple switch *67/*82 work correctly.
Next, sig_analog currently only copies over the name and number,
nothing else, when it is filling in a duplicated caller id
structure. Thus, we also now copy over the presentation
information so that is available for the Caller ID spill.
Additionally, this meant that "valid" was implicitly 0,
and as such presentation would always fail to "Unavailable".
The validity is therefore also copied over so it can be used
by ast_party_id_presentation.
As part of this fix, new API is added so that all the relevant
Caller ID information can be passed in to the Caller ID generation
functions. Parameters that are also completely missing from the
Caller ID spill have also been added, to enhance the compatibility,
correctness, and completeness of the Asterisk Caller ID implementation.
ASTERISK-29991 #close
Change-Id: Icc44a5e09979916f4c18a440f96e10dc1c76ae15
											 
										 
										
											2022-03-29 01:35:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_channel_caller ( chan ) - > id . number . presentation  =  AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_caller ( chan ) - > id . name . presentation  =  AST_PRES_PROHIB_USER_NUMBER_NOT_SCREENED ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_DIALRECALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Unable to do dial recall on channel %s: %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_channel_name ( chan ) ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												memset ( exten ,  0 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-21 14:30:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												timeout  =  analog_get_firstdigit_timeout ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  if  ( p - > callreturn  & &  ! strcmp ( exten ,  " *69 " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! ast_strlen_zero ( p - > lastcid_num ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-24 20:12:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													res  =  ast_say_digit_str ( chan ,  p - > lastcid_num ,  " " ,  ast_channel_language ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_DIALRECALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( ! strcmp ( exten ,  " *78 " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Do not disturb enabled */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_dnd ( p ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_DIALRECALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												getforward  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												memset ( exten ,  0 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( ! strcmp ( exten ,  " *79 " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Do not disturb disabled */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_dnd ( p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_DIALRECALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												getforward  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												memset ( exten ,  0 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( p - > cancallforward  & &  ! strcmp ( exten ,  " *72 " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_DIALRECALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												getforward  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												memset ( exten ,  0 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( p - > cancallforward  & &  ! strcmp ( exten ,  " *73 " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-25 19:54:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_verb ( 3 ,  " Cancelling call forwarding on channel %d \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_DIALRECALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												memset ( p - > call_forward ,  0 ,  sizeof ( p - > call_forward ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												getforward  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												memset ( exten ,  0 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												len  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-10-01 21:19:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( ( p - > transfer  | |  p - > canpark )  & &  is_exten_parking 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												& &  p - > subs [ ANALOG_SUB_THREEWAY ] . owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-01 20:55:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												struct  ast_bridge_channel  * bridge_channel ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-10-01 21:19:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  This  is  a  three  way  call ,  the  main  call  being  a  real  channel , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  and  we ' re  parking  the  first  call . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_lock ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bridge_channel  =  ast_channel_get_bridge_channel ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_unlock ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( bridge_channel )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-22 15:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! ast_parking_blind_transfer_park ( bridge_channel ,  ast_channel_context ( chan ) ,  exten ,  NULL ,  NULL ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-10-01 21:19:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 *  Swap  things  around  between  the  three - way  and  real  call  so  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 *  can  hear  where  the  channel  got  parked . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_lock_private ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_set_new_owner ( p ,  p - > subs [ ANALOG_SUB_THREEWAY ] . owner ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_swap_subs ( p ,  ANALOG_SUB_THREEWAY ,  ANALOG_SUB_REAL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_unlock_private ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_verb ( 3 ,  " %s: Parked call \n " ,  ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ao2_ref ( bridge_channel ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ao2_ref ( bridge_channel ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-01 20:55:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( ! ast_strlen_zero ( p - > lastcid_num )  & &  ! strcmp ( exten ,  " *60 " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-25 19:54:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_verb ( 3 ,  " Blacklisting number %s \n " ,  p - > lastcid_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												res  =  ast_db_put ( " blacklist " ,  p - > lastcid_num ,  " 1 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_DIALRECALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													memset ( exten ,  0 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( p - > hidecallerid  & &  ! strcmp ( exten ,  " *82 " ) )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												chan_dahdi: Fix broken hidecallerid setting.
The hidecallerid setting in chan_dahdi.conf currently
is broken for a couple reasons.
First, the actual code in sig_analog to "allow" or "block"
Caller ID depending on this setting improperly used
ast_set_callerid instead of updating the presentation.
This issue was mostly fixed in ASTERISK_29991, and that
fix is carried forward to this code as well.
Secondly, the hidecallerid setting is set on the DAHDI
pvt but not carried forward to the analog pvt properly.
This is because the chan_dahdi config loading code improperly
set permhidecallerid to permhidecallerid from the config file,
even though hidecallerid is what is actually set from the config
file. (This is done correctly for call waiting, a few lines above.)
This is fixed to read the proper value.
Thirdly, in sig_analog, hidecallerid is set to permhidecallerid
only on hangup. This can lead to potential security vulnerabilities
as an allowed Caller ID from an initial call can "leak" into subsequent
calls if no hangup occurs between them. This is fixed by setting
hidecallerid to permcallerid when calls begin, rather than when they end.
This also means we don't need to also set hidecallerid in chan_dahdi.c
when copying from the config, as we would have to otherwise.
Fourthly, sig_analog currently only allows dialing *67 or *82 if
that would actually toggle the presentation. A comment is added
clarifying that this behavior is okay.
Finally, a couple log messages are updated to be more accurate.
Resolves: #100
ASTERISK-30349 #close
(cherry picked from commit d496544d7bb0d1b839ae581d9ef2b46cbf1bf9cd)
											 
										 
										
											2023-05-18 17:37:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_verb ( 3 ,  " Allowing Caller*ID on %s \n " ,  ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												/* Enable Caller*ID if enabled */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > hidecallerid  =  0 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												chan_dahdi: Fix buggy and missing Caller ID parameters
There are several things wrong with analog Caller ID
handling that are fixed by this commit:
callerid.c's Caller ID generation function contains the
logic to use the presentation to properly send the proper
Caller ID. However, currently, DAHDI does not pass any
presentation information to the Caller ID module, which
means that presentation is completely ignored on all calls.
This means that lines could be getting Caller ID information
they aren't supposed to.
Part of the reason this has been obscured is because the
simple switch logic for handling the built in *67 and *82
is completely wrong. Rather than modifying the presentation
for the call accordingly (which is what it's supposed to do),
it simply blanks out the Caller ID or fills it in. This is
wrong, so wrong that it makes a mockery of the specification.
Additionally, it would leave to the "UNAVAILABLE" disposition
being used for Caller ID generation as opposed to the "PRIVATE"
disposition that it should have been using. This is now fixed
to only update the presentation and not modify the number and
name, so that the simple switch *67/*82 work correctly.
Next, sig_analog currently only copies over the name and number,
nothing else, when it is filling in a duplicated caller id
structure. Thus, we also now copy over the presentation
information so that is available for the Caller ID spill.
Additionally, this meant that "valid" was implicitly 0,
and as such presentation would always fail to "Unavailable".
The validity is therefore also copied over so it can be used
by ast_party_id_presentation.
As part of this fix, new API is added so that all the relevant
Caller ID information can be passed in to the Caller ID generation
functions. Parameters that are also completely missing from the
Caller ID spill have also been added, to enhance the compatibility,
correctness, and completeness of the Asterisk Caller ID implementation.
ASTERISK-29991 #close
Change-Id: Icc44a5e09979916f4c18a440f96e10dc1c76ae15
											 
										 
										
											2022-03-29 01:35:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_channel_caller ( chan ) - > id . number . presentation  =  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_caller ( chan ) - > id . name . presentation  =  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_DIALRECALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Unable to do dial recall on channel %s: %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_channel_name ( chan ) ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												memset ( exten ,  0 ,  sizeof ( exten ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-21 14:30:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												timeout  =  analog_get_firstdigit_timeout ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  if  ( ! strcmp ( exten ,  " *0 " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												struct  ast_channel  * nbridge  =  p - > subs [ ANALOG_SUB_THREEWAY ] . owner ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												struct  analog_pvt  * pbridge  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* set up the private struct of the bridged one, if any */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:17:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( nbridge )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													pbridge  =  analog_get_bridged_channel ( nbridge ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:17:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( pbridge  & &  ISTRUNK ( pbridge ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													/* Clear out the dial buffer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p - > dop . dialstr [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* flash hookswitch */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:17:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ( analog_flash ( pbridge )  = =  - 1 )  & &  ( errno  ! =  EINPROGRESS ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															" Unable to flash-hook bridged trunk from channel %s: %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															ast_channel_name ( nbridge ) ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_swap_subs ( p ,  ANALOG_SUB_REAL ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_unalloc_sub ( p ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_set_new_owner ( p ,  p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 21:21:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_queue_unhold ( p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_play_tone ( p ,  idx ,  ANALOG_TONE_CONGESTION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													analog_wait_event ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_play_tone ( p ,  idx ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													analog_swap_subs ( p ,  ANALOG_SUB_REAL ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_unalloc_sub ( p ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_set_new_owner ( p ,  p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( ! ast_canmatch_extension ( chan ,  ast_channel_context ( chan ) ,  exten ,  1 , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_channel_caller ( chan ) - > id . number . valid  ?  ast_channel_caller ( chan ) - > id . number . str  :  NULL ) 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-06 21:40:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												& &  ! analog_canmatch_featurecode ( pickupexten ,  exten ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Can't match %s from '%s' in context %s \n " ,  exten , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_channel_caller ( chan ) - > id . number . valid  & &  ast_channel_caller ( chan ) - > id . number . str 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														?  ast_channel_caller ( chan ) - > id . number . str  :  " <Unknown Caller> " , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_channel_context ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! timeout )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-03-21 14:30:18 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												timeout  =  analog_get_interdigit_timeout ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( len  & &  ! ast_ignore_pattern ( ast_channel_context ( chan ) ,  exten ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_play_tone ( p ,  idx ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXSLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_SIG_FXSKS : 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* check for SMDI messages */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p - > use_smdi  & &  p - > smdi_iface )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											smdi_msg  =  ast_smdi_md_message_wait ( p - > smdi_iface ,  ANALOG_SMDI_MD_WAIT_TIMEOUT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( smdi_msg  ! =  NULL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_channel_exten_set ( chan ,  smdi_msg - > fwd_st ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( smdi_msg - > type  = =  ' B ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													pbx_builtin_setvar_helper ( chan ,  " _SMDI_VM_TYPE " ,  " b " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												else  if  ( smdi_msg - > type  = =  ' N ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													pbx_builtin_setvar_helper ( chan ,  " _SMDI_VM_TYPE " ,  " u " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Received SMDI message on %s \n " ,  ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " SMDI enabled but no SMDI message present \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p - > use_callerid  & &  ( p - > cid_signalling  = =  CID_SIG_SMDI  & &  smdi_msg ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											number  =  smdi_msg - > calling_st ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* If we want caller id, we're in a prering state due to a polarity reversal
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  and  we ' re  set  to  use  a  polarity  reversal  to  trigger  the  start  of  caller  id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  grab  the  caller  id  and  wait  for  ringing  to  start . . .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( p - > use_callerid  & &  ( ast_channel_state ( chan )  = =  AST_STATE_PRERING 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											& &  ( p - > cid_start  = =  ANALOG_CID_START_POLARITY 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												| |  p - > cid_start  = =  ANALOG_CID_START_POLARITY_IN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												| |  p - > cid_start  = =  ANALOG_CID_START_DTMF_NOALERT ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											/* If set to use DTMF CID signalling, listen for DTMF */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p - > cid_signalling  = =  CID_SIG_DTMF )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												int  k  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-25 04:06:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												int  oldlinearity ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-07 19:15:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												int  timeout_ms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												int  ms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												struct  timeval  start  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Receiving DTMF cid on channel %s \n " ,  ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												oldlinearity  =  analog_set_linear_mode ( p ,  idx ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 22:44:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  We  are  the  only  party  interested  in  the  Rx  stream  since 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  we  have  not  answered  yet .   We  don ' t  need  or  even  want  DTMF 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  emulation .   The  DTMF  digits  can  come  so  fast  that  emulation 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  can  drop  some  of  them . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 */ 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-12 15:13:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-13 18:20:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_set_flag ( ast_channel_flags ( chan ) ,  AST_FLAG_END_DTMF_ONLY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-12 15:13:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-07 19:15:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												timeout_ms  =  4000 ; /* This is a typical OFF time between rings. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													struct  ast_frame  * f ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-07 19:15:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ms  =  ast_remaining_ms ( start ,  timeout_ms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  ast_waitfor ( chan ,  ms ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													if  ( res  < =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 22:44:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 *  We  do  not  need  to  restore  the  analog_set_linear_mode ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 *  or  AST_FLAG_END_DTMF_ONLY  flag  settings  since  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 *  are  hanging  up  the  channel . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 */ 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-20 17:55:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															" DTMFCID timed out waiting for ring. Exiting simple switch \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													f  =  ast_read ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( ! f )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													if  ( f - > frametype  = =  AST_FRAME_DTMF )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( k  <  ARRAY_LEN ( dtmfbuf )  -  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															dtmfbuf [ k + + ]  =  f - > subclass . integer ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 22:44:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " CID got digit '%c' \n " ,  f - > subclass . integer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-07 19:15:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														start  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ast_channel_state ( chan )  = =  AST_STATE_RING  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_channel_state ( chan )  = =  AST_STATE_RINGING )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														break ;  /* Got ring */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-12 15:13:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-13 18:20:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_clear_flag ( ast_channel_flags ( chan ) ,  AST_FLAG_END_DTMF_ONLY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-06-12 15:13:14 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												dtmfbuf [ k ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_set_linear_mode ( p ,  idx ,  oldlinearity ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												/* Got cid and ring. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " CID got string '%s' \n " ,  dtmfbuf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												callerid_get_dtmf ( dtmfbuf ,  dtmfcid ,  & flags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 22:44:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " CID is '%s', flags %d \n " ,  dtmfcid ,  flags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												/* If first byte is NULL, we have no cid */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! ast_strlen_zero ( dtmfcid ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													number  =  dtmfcid ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													number  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											/* If set to use V23 Signalling, launch our FSK gubbins and listen for it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( ( p - > cid_signalling  = =  CID_SIG_V23 )  | |  ( p - > cid_signalling  = =  CID_SIG_V23_JP ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												namebuf [ 0 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												numbuf [ 0 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! analog_start_cid_detect ( p ,  p - > cid_signalling ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													int  timeout  =  10000 ;   /* Ten seconds */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													struct  timeval  start  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													enum  analog_event  ev ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-07 19:15:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													int  off_ms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													int  ms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													struct  timeval  off_start ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 16:24:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! p - > usedistinctiveringdetection )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/* Disable distinctive ring timeout count */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_set_ringtimeout ( p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													while  ( ( ms  =  ast_remaining_ms ( start ,  timeout ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														res  =  analog_get_callerid ( p ,  namebuf ,  numbuf ,  & ev ,  ms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																" CallerID returned with error on channel '%s' \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( res  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( res  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( ev  = =  ANALOG_EVENT_NOALARM )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															analog_set_alarm ( p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( p - > cid_signalling  = =  CID_SIG_V23_JP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															if  ( ev  = =  ANALOG_EVENT_RINGBEGIN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																analog_off_hook ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																usleep ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															break ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													name  =  namebuf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													number  =  numbuf ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 16:24:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													if  ( p - > cid_signalling  = =  CID_SIG_V23_JP )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														analog_on_hook ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														usleep ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-29 22:44:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													/* Finished with Caller*ID, now wait for a ring to make sure there really is a call coming */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-07 19:15:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													off_start  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													off_ms  =  4000 ; /* This is a typical OFF time between rings. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													while  ( ( ms  =  ast_remaining_ms ( off_start ,  off_ms ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														struct  ast_frame  * f ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-11-07 19:15:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														res  =  ast_waitfor ( chan ,  ms ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														if  ( res  < =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-20 17:55:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																" CID timed out waiting for ring. Exiting simple switch \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															analog_stop_cid_detect ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															goto  quit ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														if  ( ! ( f  =  ast_read ( chan ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_log ( LOG_WARNING ,  " Hangup received waiting for ring. Exiting simple switch \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															analog_stop_cid_detect ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( ast_channel_state ( chan )  = =  AST_STATE_RING  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_channel_state ( chan )  = =  AST_STATE_RINGING ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															break ;  /* Got ring */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													res  =  analog_distinctive_ring ( chan ,  p ,  idx ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_stop_cid_detect ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														goto  quit ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Unable to get caller ID space \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-20 17:55:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Channel %s in prering state, but I have nothing to do. Terminating simple switch, should be restarted by the actual ring. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( p - > use_callerid  & &  p - > cid_start  = =  ANALOG_CID_START_RING )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											namebuf [ 0 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											numbuf [ 0 ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! analog_start_cid_detect ( p ,  p - > cid_signalling ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												int  timeout  =  10000 ;   /* Ten seconds */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												struct  timeval  start  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												enum  analog_event  ev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												int  ring_data [ RING_PATTERNS ]  =  {  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												int  ring_data_idx  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												int  ms ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! p - > usedistinctiveringdetection )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Disable distinctive ring timeout count */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_set_ringtimeout ( p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												while  ( ( ms  =  ast_remaining_ms ( start ,  timeout ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  analog_get_callerid ( p ,  namebuf ,  numbuf ,  & ev ,  ms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															" CallerID returned with error on channel '%s' \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_channel_name ( chan ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													if  ( res  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( res  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ev  = =  ANALOG_EVENT_NOALARM )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_set_alarm ( p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( ev  = =  ANALOG_EVENT_POLARITY 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														& &  p - > hanguponpolarityswitch 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														& &  p - > polarity  = =  POLARITY_REV )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															" Hanging up due to polarity reversal on channel %d while detecting callerid \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														p - > polarity  =  POLARITY_IDLE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_stop_cid_detect ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( ev  = =  ANALOG_EVENT_RINGOFFHOOK 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														& &  p - > usedistinctiveringdetection 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														& &  ring_data_idx  <  RING_PATTERNS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 *  Detect  callerid  while  collecting  possible 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 *  distinctive  ring  pattern . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ring_data [ ring_data_idx ]  =  p - > ringt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														+ + ring_data_idx ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												name  =  namebuf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												number  =  numbuf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												res  =  analog_distinctive_ring ( chan ,  p ,  idx ,  ring_data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												analog_stop_cid_detect ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-06 20:24:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													goto  quit ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Unable to get caller ID space \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( number )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_shrink_phone_number ( number ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_set_callerid ( chan ,  number ,  name ,  number ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_handle_notify_message ( chan ,  p ,  flags ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-12-18 20:33:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_setstate ( chan ,  AST_STATE_RING ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_rings_set ( chan ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-12-18 20:33:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-12 20:47:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_ringtimeout ( p ,  p - > ringt_base ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										res  =  ast_pbx_run ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " PBX exited non-zero \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  quit ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Don't know how to handle simple switch with signalling %s on channel %d \n " ,  analog_sigtype_to_str ( p - > sig ) ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-06 20:15:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  analog_play_tone ( p ,  idx ,  ANALOG_TONE_CONGESTION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-06 20:15:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Unable to play congestion tone on channel %d \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								quit :  
						 
					
						
							
								
									
										
										
										
											2014-07-21 08:41:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ao2_cleanup ( smdi_msg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									analog_decrease_ss_count ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  analog_ss_thread_start ( struct  analog_pvt  * p ,  struct  ast_channel  * chan )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pthread_t  threadid ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-06 20:15:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ast_pthread_create_detached ( & threadid ,  NULL ,  __analog_ss_thread ,  p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-07-01 13:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_publish_channel_alarm_clear ( int  channel )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RAII_VAR ( struct  ast_json  * ,  body ,  NULL ,  ast_json_unref ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_log ( LOG_NOTICE ,  " Alarm cleared on channel %d \n " ,  channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									body  =  ast_json_pack ( " {s: i} " ,  " Channel " ,  channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! body )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_manager_publish_event ( " AlarmClear " ,  EVENT_FLAG_SYSTEM ,  body ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  struct  ast_frame  * __analog_handle_event ( struct  analog_pvt  * p ,  struct  ast_channel  * ast )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ,  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  mysig ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-02-01 12:04:06 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  idx ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									char  * c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pthread_t  threadid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  * f ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-06 22:03:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_control_pvt_cause_code  * cause_code  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-22 15:10:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  data_size  =  sizeof ( * cause_code ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * subclass  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " %s %d \n " ,  __FUNCTION__ ,  p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									idx  =  analog_get_index ( ast ,  p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( idx  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( idx  ! =  ANALOG_SUB_REAL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " We got an event on a non real sub.  Fix it! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									mysig  =  p - > sig ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( p - > outsigmod  >  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										mysig  =  p - > outsigmod ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . frametype  =  AST_FRAME_NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . subclass . integer  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . datalen  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . samples  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . mallocd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . src  =  " dahdi_handle_event " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . data . ptr  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									f  =  & p - > subs [ idx ] . f ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  analog_get_event ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Got event %s(%d) on channel %d (index %u) \n " ,  analog_event2str ( res ) ,  res ,  p - > channel ,  idx ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res  &  ( ANALOG_EVENT_PULSEDIGIT  |  ANALOG_EVENT_DTMFUP ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-11 20:38:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_pulsedial ( p ,  ( res  &  ANALOG_EVENT_PULSEDIGIT )  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Detected %sdigit '%c' \n " ,  ( res  &  ANALOG_EVENT_PULSEDIGIT )  ?  " pulse  " :  " " ,  res  &  0xff ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_confmute ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
											
												chan_dahdi: Add dialmode option for FXS lines. (#36)
Currently, both pulse and tone dialing are always enabled
on all FXS lines, with no way of disabling one or the other.
In some circumstances, it is desirable or necessary to
disable one of these, and this behavior can be problematic.
A new "dialmode" option is added which allows setting the
methods to support on a per channel basis for FXS (FXO
signalled lines). The four options are "both", "pulse",
"dtmf"/"tone", and "none".
Additionally, integration with the CHANNEL function is
added so that this setting can be updated for a channel
during a call.
Resolves: #35
ASTERISK-29992
UserNote: A "dialmode" option has been added which allows
specifying, on a per-channel basis, what methods of
subscriber dialing (pulse and/or tone) are permitted.
Additionally, this can be changed on a channel
at any point during a call using the CHANNEL
function.
(cherry picked from commit 5d1dd11143cf9fc899881476a1898aecf42e95ae)
											 
										 
										
											2023-05-02 09:05:12 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p - > dialmode  = =  ANALOG_DIALMODE_BOTH  | |  p - > dialmode  = =  ANALOG_DIALMODE_PULSE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > subs [ idx ] . f . frametype  =  AST_FRAME_DTMF_END ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > subs [ idx ] . f . subclass . integer  =  res  &  0xff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_handle_dtmf ( p ,  ast ,  idx ,  & f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Dropping pulse digit '%c' because pulse dialing disabled on channel %d \n " ,  res  &  0xff ,  p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  &  ANALOG_EVENT_DTMFDOWN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " DTMF Down '%c' \n " ,  res  &  0xff ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Mute conference */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_confmute ( p ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p - > subs [ idx ] . f . frametype  =  AST_FRAME_DTMF_BEGIN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p - > subs [ idx ] . f . subclass . integer  =  res  &  0xff ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_handle_dtmf ( p ,  ast ,  idx ,  & f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-06 22:03:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_ALARM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_POLARITY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_ONHOOK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* add length of "ANALOG " */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										data_size  + =  7 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										subclass  =  analog_event2str ( res ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										data_size  + =  strlen ( subclass ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-31 20:21:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cause_code  =  ast_alloca ( data_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-08-27 16:51:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										memset ( cause_code ,  0 ,  data_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-20 15:48:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cause_code - > ast_cause  =  AST_CAUSE_NORMAL_CLEARING ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-06 22:03:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_copy_string ( cause_code - > chan_name ,  ast_channel_name ( ast ) ,  AST_CHANNEL_NAME ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										snprintf ( cause_code - > code ,  data_size  -  sizeof ( * cause_code )  +  1 ,  " ANALOG %s " ,  subclass ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-22 15:10:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									switch  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_EC_DISABLED : 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-01 00:49:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_verb ( 3 ,  " Channel %d echo canceller disabled due to CED detection \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_echocanceller ( p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef HAVE_DAHDI_ECHOCANCEL_FAX_MODE 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_TX_CED_DETECTED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verb ( 3 ,  " Channel %d detected a CED tone towards the network. \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_RX_CED_DETECTED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verb ( 3 ,  " Channel %d detected a CED tone from the network. \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_EC_NLP_DISABLED : 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-01 00:49:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_verb ( 3 ,  " Channel %d echo canceller disabled its NLP. \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-05 19:20:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_EC_NLP_ENABLED : 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-01 00:49:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_verb ( 3 ,  " Channel %d echo canceller enabled its NLP. \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_PULSE_START : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Stop tone if there's a pulse start and the PBX isn't started */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ast_channel_pbx ( ast ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											analog_play_tone ( p ,  ANALOG_SUB_REAL ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_DIALCOMPLETE : 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p - > inalarm )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										x  =  analog_is_dialing ( p ,  idx ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( ! x )  {  /* if not still dialing in driver */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_set_echocanceller ( p ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p - > echobreak )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_train_echocanceller ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_copy_string ( p - > dop . dialstr ,  p - > echorest ,  sizeof ( p - > dop . dialstr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > dop . op  =  ANALOG_DIAL_OP_REPLACE ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-28 18:27:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_dial_digits ( p ,  ANALOG_SUB_REAL ,  & p - > dop ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												p - > echobreak  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 22:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_set_dialing ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												if  ( ( mysig  = =  ANALOG_SIG_E911 )  | |  ( mysig  = =  ANALOG_SIG_FGC_CAMA )  | |  ( mysig  = =  ANALOG_SIG_FGC_CAMAMF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* if thru with dialing after offhook */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ast_channel_state ( ast )  = =  AST_STATE_DIALING_OFFHOOK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_setstate ( ast ,  AST_STATE_UP ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														p - > subs [ idx ] . f . frametype  =  AST_FRAME_CONTROL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														p - > subs [ idx ] . f . subclass . integer  =  AST_CONTROL_ANSWER ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  {  /* if to state wait for offhook to dial rest */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/* we now wait for off hook */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_setstate ( ast , AST_STATE_DIALING_OFFHOOK ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ast_channel_state ( ast )  = =  AST_STATE_DIALING )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-05 17:44:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( analog_have_progressdetect ( p ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " Done dialing, but waiting for progress detection before doing more... \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( analog_check_confirmanswer ( p )  | |  ( ! p - > dialednone 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														& &  ( ( mysig  = =  ANALOG_SIG_EM )  | |  ( mysig  = =  ANALOG_SIG_EM_E1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															| |  ( mysig  = =  ANALOG_SIG_EMWINK )  | |  ( mysig  = =  ANALOG_SIG_FEATD ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															| |  ( mysig  = =  ANALOG_SIG_FEATDMF_TA )  | |  ( mysig  = =  ANALOG_SIG_FEATDMF ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															| |  ( mysig  = =  ANALOG_SIG_E911 )  | |  ( mysig  = =  ANALOG_SIG_FGC_CAMA ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															| |  ( mysig  = =  ANALOG_SIG_FGC_CAMAMF )  | |  ( mysig  = =  ANALOG_SIG_FEATB ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															| |  ( mysig  = =  ANALOG_SIG_SF )  | |  ( mysig  = =  ANALOG_SIG_SFWINK ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															| |  ( mysig  = =  ANALOG_SIG_SF_FEATD )  | |  ( mysig  = =  ANALOG_SIG_SF_FEATDMF ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															| |  ( mysig  = =  ANALOG_SIG_SF_FEATB ) ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_setstate ( ast ,  AST_STATE_RINGING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( ! p - > answeronpolarityswitch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_setstate ( ast ,  AST_STATE_UP ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														p - > subs [ idx ] . f . frametype  =  AST_FRAME_CONTROL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														p - > subs [ idx ] . f . subclass . integer  =  AST_CONTROL_ANSWER ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														/* If aops=0 and hops=1, this is necessary */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														p - > polarity  =  POLARITY_REV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/* Start clean, so we can catch the change to REV polarity when party answers */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														p - > polarity  =  POLARITY_IDLE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_ALARM : 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-04 21:10:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_alarm ( p ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_get_and_handle_alarms ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-20 15:48:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										cause_code - > ast_cause  =  AST_CAUSE_NETWORK_OUT_OF_ORDER ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_ONHOOK : 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-06 22:03:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_queue_control_data ( ast ,  AST_CONTROL_PVT_CAUSE_CODE ,  cause_code ,  data_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-15 17:56:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_hangupcause_hash_set ( ast ,  cause_code ,  data_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										switch  ( p - > sig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOKS : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 23:14:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_start_polarityswitch ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p - > fxsoffhookstate  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > onhooktime  =  time ( NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > msgstate  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											/* Check for some special conditions regarding call waiting */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( idx  = =  ANALOG_SUB_REAL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												/* The normal line was hung up */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( p - > subs [ ANALOG_SUB_CALLWAIT ] . owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													/* Need to hold the lock for real-call, private, and call-waiting call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_lock_sub_owner ( p ,  ANALOG_SUB_CALLWAIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( ! p - > subs [ ANALOG_SUB_CALLWAIT ] . owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/*
 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-01 00:49:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														 *  The  call  waiting  call  disappeared . 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														 *  This  is  now  a  normal  hangup . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_set_echocanceller ( p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-01 00:49:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													/* There's a call waiting call, so ring the phone, but make it unowned in the meantime */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													analog_swap_subs ( p ,  ANALOG_SUB_CALLWAIT ,  ANALOG_SUB_REAL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-25 19:54:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_verb ( 3 ,  " Channel %d still has (callwait) call, ringing phone \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													analog_unalloc_sub ( p ,  ANALOG_SUB_CALLWAIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_stop_callwait ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_set_new_owner ( p ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													/* Don't start streaming audio yet if the incoming call isn't up yet */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ast_channel_state ( p - > subs [ ANALOG_SUB_REAL ] . owner )  ! =  AST_STATE_UP )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 22:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														analog_set_dialing ( p ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													/* Unlock the call-waiting call that we swapped to real-call. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_channel_unlock ( p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													analog_ring ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													unsigned  int  mssinceflash ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Need to hold the lock for real-call, private, and 3-way call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_lock_sub_owner ( p ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													if  ( ! p - > subs [ ANALOG_SUB_THREEWAY ] . owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_NOTICE ,  " Whoa, threeway disappeared kinda randomly. \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														/* Just hangup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( p - > owner  ! =  ast )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_channel_unlock ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING ,  " This isn't good... \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/* Just hangup */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													mssinceflash  =  ast_tvdiff_ms ( ast_tvnow ( ) ,  p - > flashtime ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Last flash was %u ms ago \n " ,  mssinceflash ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													if  ( mssinceflash  <  MIN_MS_SINCE_FLASH )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/* It hasn't been long enough since the last flashook.  This is probably a bounce on
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														   hanging  up .   Hangup  both  channels  now  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " Looks like a bounced flash, hanging up both calls on %d \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_queue_hangup_with_cause ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ,  AST_CAUSE_NO_ANSWER ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_softhangup_nolock ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ,  AST_SOFTHANGUP_DEV ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_channel_unlock ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													}  else  if  ( ( ast_channel_pbx ( ast ) )  | |  ( ast_channel_state ( ast )  = =  AST_STATE_UP ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														if  ( p - > transfer )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-09 17:00:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															/* In any case this isn't a threeway call anymore */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															analog_set_inthreeway ( p ,  ANALOG_SUB_REAL ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															analog_set_inthreeway ( p ,  ANALOG_SUB_THREEWAY ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															/* Only attempt transfer if the phone is ringing; why transfer to busy tone eh? */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															if  ( ! p - > transfertobusy  & &  ast_channel_state ( ast )  = =  AST_STATE_BUSY )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
																/* Swap subs and dis-own channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																analog_swap_subs ( p ,  ANALOG_SUB_THREEWAY ,  ANALOG_SUB_REAL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																/* Unlock the 3-way call that we swapped to real-call. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																ast_channel_unlock ( p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																analog_set_new_owner ( p ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
																/* Ring the phone */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																analog_ring ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-06-07 01:06:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															}  else  if  ( ! analog_attempt_transfer ( p ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																 *  Transfer  successful .   Don ' t  actually  hang  up  at  this  point . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																 *  Let  our  channel  legs  of  the  calls  die  off  as  the  transfer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																 *  percolates  through  the  core . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
																break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_softhangup_nolock ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ,  AST_SOFTHANGUP_DEV ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															ast_channel_unlock ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/* Swap subs and dis-own channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_swap_subs ( p ,  ANALOG_SUB_THREEWAY ,  ANALOG_SUB_REAL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														/* Unlock the 3-way call that we swapped to real-call. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_channel_unlock ( p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														analog_set_new_owner ( p ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														/* Ring the phone */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_ring ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Got a hangup and my index is %u? \n " ,  idx ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_set_echocanceller ( p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_RINGOFFHOOK : 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p - > inalarm )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* for E911, its supposed to wait for offhook then dial
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   the  second  half  of  the  dial  string  */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( ( mysig  = =  ANALOG_SIG_E911 )  | |  ( mysig  = =  ANALOG_SIG_FGC_CAMA )  | |  ( mysig  = =  ANALOG_SIG_FGC_CAMAMF ) )  & &  ( ast_channel_state ( ast )  = =  AST_STATE_DIALING_OFFHOOK ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											c  =  strchr ( p - > dialdest ,  ' / ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( c )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												c + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												c  =  p - > dialdest ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-17 11:11:49 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( * c )  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-17 11:11:49 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												int  numchars  =  snprintf ( p - > dop . dialstr ,  sizeof ( p - > dop . dialstr ) ,  " M*0%s# " ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( numchars  > =  sizeof ( p - > dop . dialstr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Dial string '%s' truncated \n " ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_copy_string ( p - > dop . dialstr , " M*2# " ,  sizeof ( p - > dop . dialstr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-06-17 11:11:49 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( strlen ( p - > dop . dialstr )  >  4 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												memset ( p - > echorest ,  ' w ' ,  sizeof ( p - > echorest )  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												strcpy ( p - > echorest  +  ( p - > echotraining  /  401 )  +  1 ,  p - > dop . dialstr  +  strlen ( p - > dop . dialstr )  -  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > echorest [ sizeof ( p - > echorest )  -  1 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > echobreak  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > dop . dialstr [ strlen ( p - > dop . dialstr ) - 2 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												p - > echobreak  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( analog_dial_digits ( p ,  ANALOG_SUB_REAL ,  & p - > dop ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_on_hook ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 22:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_set_dialing ( p ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  & p - > subs [ idx ] . f ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( p - > sig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOKS : 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p - > fxsoffhookstate  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											switch  ( ast_channel_state ( ast ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  AST_STATE_RINGING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_set_echocanceller ( p ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_train_echocanceller ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p - > subs [ idx ] . f . frametype  =  AST_FRAME_CONTROL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > subs [ idx ] . f . subclass . integer  =  AST_CONTROL_ANSWER ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												/* Make sure it stops ringing */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-30 22:36:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_set_needringing ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												analog_off_hook ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " channel %d answered \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Cancel any running CallerID spill */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-10 20:18:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_cancel_cidspill ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 22:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_set_dialing ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												p - > callwaitcas  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 22:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( analog_check_confirmanswer ( p ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Ignore answer if "confirm answer" is enabled */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													p - > subs [ idx ] . f . frametype  =  AST_FRAME_NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p - > subs [ idx ] . f . subclass . integer  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 22:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  if  ( ! ast_strlen_zero ( p - > dop . dialstr ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													/* nick@dccinc.com 4/3/03 - fxo should be able to do deferred dialing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  analog_dial_digits ( p ,  ANALOG_SUB_REAL ,  & p - > dop ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-28 18:27:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														p - > dop . dialstr [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " Sent FXO deferred digit string: %s \n " ,  p - > dop . dialstr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														p - > subs [ idx ] . f . frametype  =  AST_FRAME_NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														p - > subs [ idx ] . f . subclass . integer  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 22:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														analog_set_dialing ( p ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p - > dop . dialstr [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_setstate ( ast ,  AST_STATE_DIALING ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_setstate ( ast ,  AST_STATE_UP ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 23:14:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_answer_polarityswitch ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  & p - > subs [ idx ] . f ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  AST_STATE_DOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_setstate ( ast ,  AST_STATE_RING ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_channel_rings_set ( ast ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p - > subs [ idx ] . f . frametype  =  AST_FRAME_CONTROL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > subs [ idx ] . f . subclass . integer  =  AST_CONTROL_OFFHOOK ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " channel %d picked up \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  & p - > subs [ idx ] . f ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											case  AST_STATE_UP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Make sure it stops ringing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_off_hook ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-01 20:00:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Okay -- probably call waiting */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 21:21:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_queue_unhold ( p - > owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  AST_STATE_RESERVED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Start up dialtone */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( analog_has_voicemail ( p ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													res  =  analog_play_tone ( p ,  ANALOG_SUB_REAL ,  ANALOG_TONE_STUTTER ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													res  =  analog_play_tone ( p ,  ANALOG_SUB_REAL ,  ANALOG_TONE_DIALTONE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " FXO phone off hook in weird state %u?? \n " ,  ast_channel_state ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSKS : 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ast_channel_state ( ast )  = =  AST_STATE_RING )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-12 20:47:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_set_ringtimeout ( p ,  p - > ringt_base ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EM_E1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EMWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATDMF_TA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_E911 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FGC_CAMA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FGC_CAMAMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SFWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATB : 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											switch  ( ast_channel_state ( ast ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-15 18:30:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											case  AST_STATE_PRERING : 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_setstate ( ast ,  AST_STATE_RING ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-15 18:30:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  AST_STATE_DOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  AST_STATE_RING : 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Ring detected \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												p - > subs [ idx ] . f . frametype  =  AST_FRAME_CONTROL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												p - > subs [ idx ] . f . subclass . integer  =  AST_CONTROL_RING ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-15 18:30:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  AST_STATE_RINGING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  AST_STATE_DIALING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( p - > outgoing )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Line answered \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( analog_check_confirmanswer ( p ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														p - > subs [ idx ] . f . frametype  =  AST_FRAME_NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														p - > subs [ idx ] . f . subclass . integer  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-15 18:30:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														p - > subs [ idx ] . f . frametype  =  AST_FRAME_CONTROL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														p - > subs [ idx ] . f . subclass . integer  =  AST_CONTROL_ANSWER ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-15 18:30:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_setstate ( ast ,  AST_STATE_UP ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 22:39:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-15 18:30:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Ring/Off-hook in strange state %u on channel %d \n " ,  ast_channel_state ( ast ) ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-15 18:30:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Don't know how to handle ring/off hook for signalling %d \n " ,  p - > sig ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-15 18:30:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_RINGBEGIN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( p - > sig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSKS : 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ast_channel_state ( ast )  = =  AST_STATE_RING )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-12 20:47:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_set_ringtimeout ( p ,  p - > ringt_base ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-01 18:50:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_RINGEROFF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p - > inalarm )  break ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_rings_set ( ast ,  ast_channel_rings ( ast )  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_channel_rings ( ast )  = =  p - > cidrings )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_send_callerid ( p ,  0 ,  & p - > caller ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_channel_rings ( ast )  >  p - > cidrings )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-10 20:18:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_cancel_cidspill ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											p - > callwaitcas  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										p - > subs [ idx ] . f . frametype  =  AST_FRAME_CONTROL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										p - > subs [ idx ] . f . subclass . integer  =  AST_CONTROL_RINGING ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_RINGERON : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_NOALARM : 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-04 21:10:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_alarm ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-01 13:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_publish_channel_alarm_clear ( p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_WINKFLASH : 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p - > inalarm )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Remember last time we got a flash-hook */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										gettimeofday ( & p - > flashtime ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( mysig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOKS : 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Winkflash, index: %u, normal: %d, callwait: %d, thirdcall: %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												idx ,  analog_get_sub_fd ( p ,  ANALOG_SUB_REAL ) ,  analog_get_sub_fd ( p ,  ANALOG_SUB_CALLWAIT ) ,  analog_get_sub_fd ( p ,  ANALOG_SUB_THREEWAY ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Cancel any running CallerID spill */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_cancel_cidspill ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											p - > callwaitcas  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( idx  ! =  ANALOG_SUB_REAL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Got flash hook with index %u on channel %d?!? \n " ,  idx ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												goto  winkflashdone ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p - > subs [ ANALOG_SUB_CALLWAIT ] . owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Need to hold the lock for real-call, private, and call-waiting call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_lock_sub_owner ( p ,  ANALOG_SUB_CALLWAIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! p - > subs [ ANALOG_SUB_CALLWAIT ] . owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  The  call  waiting  call  dissappeared . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  Let ' s  just  ignore  this  flash - hook . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_NOTICE ,  " Whoa, the call-waiting call disappeared. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  winkflashdone ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Swap to call-wait */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												analog_swap_subs ( p ,  ANALOG_SUB_REAL ,  ANALOG_SUB_CALLWAIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_play_tone ( p ,  ANALOG_SUB_REAL ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_set_new_owner ( p ,  p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Making %s the new owner \n " ,  ast_channel_name ( p - > owner ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ast_channel_state ( p - > subs [ ANALOG_SUB_REAL ] . owner )  = =  AST_STATE_RINGING )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_setstate ( p - > subs [ ANALOG_SUB_REAL ] . owner ,  AST_STATE_UP ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_queue_control ( p - > subs [ ANALOG_SUB_REAL ] . owner ,  AST_CONTROL_ANSWER ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_stop_callwait ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												/* Start music on hold if appropriate */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-01 20:00:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! p - > subs [ ANALOG_SUB_CALLWAIT ] . inthreeway )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 21:21:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_queue_hold ( p - > subs [ ANALOG_SUB_CALLWAIT ] . owner ,  p - > mohsuggest ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 21:21:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_queue_hold ( p - > subs [ ANALOG_SUB_REAL ] . owner ,  p - > mohsuggest ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_queue_unhold ( p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Unlock the call-waiting call that we swapped to real-call. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_unlock ( p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  if  ( ! p - > subs [ ANALOG_SUB_THREEWAY ] . owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! p - > threewaycalling )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Just send a flash if no 3-way calling */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_queue_control ( p - > subs [ ANALOG_SUB_REAL ] . owner ,  AST_CONTROL_FLASH ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  winkflashdone ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ! analog_check_for_conference ( p ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-13 01:12:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_callid  callid  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													int  callid_created ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													char  cid_num [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													char  cid_name [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													cid_num [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													cid_name [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													if  ( p - > dahditrcallerid  & &  p - > owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( ast_channel_caller ( p - > owner ) - > id . number . valid 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															& &  ast_channel_caller ( p - > owner ) - > id . number . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_copy_string ( cid_num ,  ast_channel_caller ( p - > owner ) - > id . number . str , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																sizeof ( cid_num ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( ast_channel_caller ( p - > owner ) - > id . name . valid 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															& &  ast_channel_caller ( p - > owner ) - > id . name . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_copy_string ( cid_name ,  ast_channel_caller ( p - > owner ) - > id . name . str , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																sizeof ( cid_name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* XXX This section needs much more error checking!!! XXX */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Start a 3-way call if feasible */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! ( ( ast_channel_pbx ( ast ) )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														( ast_channel_state ( ast )  = =  AST_STATE_UP )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														( ast_channel_state ( ast )  = =  AST_STATE_RING ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " Flash when call not up or ringing \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														goto  winkflashdone ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( analog_alloc_sub ( p ,  ANALOG_SUB_THREEWAY ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING ,  " Unable to allocate three-way subchannel \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														goto  winkflashdone ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-06 21:34:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													callid_created  =  ast_callid_threadstorage_auto ( & callid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-06-06 21:34:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  Make  new  channel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  We  cannot  hold  the  p  or  ast  locks  while  creating  a  new 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  channel . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_unlock_private ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_channel_unlock ( ast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													chan  =  analog_new_ast_channel ( p ,  AST_STATE_RESERVED ,  0 ,  ANALOG_SUB_THREEWAY ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-06 21:34:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_channel_lock ( ast ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_lock_private ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															" Cannot allocate new call structure on channel %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_unalloc_sub ( p ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_callid_threadstorage_auto_clean ( callid ,  callid_created ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														goto  winkflashdone ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													if  ( p - > dahditrcallerid )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( ! p - > origcid_num )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															p - > origcid_num  =  ast_strdup ( p - > cid_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( ! p - > origcid_name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															p - > origcid_name  =  ast_strdup ( p - > cid_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_copy_string ( p - > cid_num ,  cid_num ,  sizeof ( p - > cid_num ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_copy_string ( p - > cid_name ,  cid_name ,  sizeof ( p - > cid_name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Swap things around between the three-way and real call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_swap_subs ( p ,  ANALOG_SUB_THREEWAY ,  ANALOG_SUB_REAL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Disable echo canceller for better dialing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_set_echocanceller ( p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  analog_play_tone ( p ,  ANALOG_SUB_REAL ,  ANALOG_TONE_DIALRECALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING ,  " Unable to start dial recall tone on channel %d \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_set_new_owner ( p ,  chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													p - > ss_astchan  =  chan ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ast_pthread_create_detached ( & threadid ,  NULL ,  __analog_ss_thread ,  p ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING ,  " Unable to start simple switch on channel %d \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														res  =  analog_play_tone ( p ,  ANALOG_SUB_REAL ,  ANALOG_TONE_CONGESTION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_set_echocanceller ( p ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-25 19:54:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_verb ( 3 ,  " Started three way call on channel %d \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-30 01:55:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-05-01 20:00:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														/* Start music on hold */ 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 21:21:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_queue_hold ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ,  p - > mohsuggest ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_callid_threadstorage_auto_clean ( callid ,  callid_created ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Already have a 3 way call */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												enum  analog_sub  orig_3way_sub ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Need to hold the lock for real-call, private, and 3-way call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_lock_sub_owner ( p ,  ANALOG_SUB_THREEWAY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! p - > subs [ ANALOG_SUB_THREEWAY ] . owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  The  3 - way  call  dissappeared . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  Let ' s  just  ignore  this  flash - hook . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_NOTICE ,  " Whoa, the 3-way call disappeared. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													goto  winkflashdone ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												orig_3way_sub  =  ANALOG_SUB_THREEWAY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												if  ( p - > subs [ ANALOG_SUB_THREEWAY ] . inthreeway )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Call is already up, drop the last person */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Got flash with three way call up, dropping last call on %d \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* If the primary call isn't answered yet, use it */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ( ast_channel_state ( p - > subs [ ANALOG_SUB_REAL ] . owner )  ! =  AST_STATE_UP )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														( ast_channel_state ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner )  = =  AST_STATE_UP ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														/* Swap back -- we're dropping the real 3-way that isn't finished yet*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_swap_subs ( p ,  ANALOG_SUB_THREEWAY ,  ANALOG_SUB_REAL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														orig_3way_sub  =  ANALOG_SUB_REAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														analog_set_new_owner ( p ,  p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Drop the last call and stop the conference */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_verb ( 3 ,  " Dropping three-way call on %s \n " ,  ast_channel_name ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_softhangup_nolock ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ,  AST_SOFTHANGUP_DEV ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-01 17:32:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_set_inthreeway ( p ,  ANALOG_SUB_REAL ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_set_inthreeway ( p ,  ANALOG_SUB_THREEWAY ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Lets see what we're up to */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ( ( ast_channel_pbx ( ast ) )  | |  ( ast_channel_state ( ast )  = =  AST_STATE_UP ) )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														( p - > transfertobusy  | |  ( ast_channel_state ( ast )  ! =  AST_STATE_BUSY ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-03 18:38:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_verb ( 3 ,  " Building conference call with %s and %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															ast_channel_name ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_channel_name ( p - > subs [ ANALOG_SUB_REAL ] . owner ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														/* Put them in the threeway, and flip */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-01 17:32:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														analog_set_inthreeway ( p ,  ANALOG_SUB_THREEWAY ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														analog_set_inthreeway ( p ,  ANALOG_SUB_REAL ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-13 12:33:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														analog_swap_subs ( p ,  ANALOG_SUB_THREEWAY ,  ANALOG_SUB_REAL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														orig_3way_sub  =  ANALOG_SUB_REAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 21:21:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_queue_unhold ( p - > subs [ orig_3way_sub ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														analog_set_new_owner ( p ,  p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_verb ( 3 ,  " Dumping incomplete call on %s \n " ,  ast_channel_name ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														analog_swap_subs ( p ,  ANALOG_SUB_THREEWAY ,  ANALOG_SUB_REAL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														orig_3way_sub  =  ANALOG_SUB_REAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_softhangup_nolock ( p - > subs [ ANALOG_SUB_THREEWAY ] . owner ,  AST_SOFTHANGUP_DEV ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														analog_set_new_owner ( p ,  p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 21:21:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_queue_unhold ( p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														analog_set_echocanceller ( p ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_channel_unlock ( p - > subs [ orig_3way_sub ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								winkflashdone :  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											analog_update_conf ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EM_E1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SFWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( p - > dialing )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Ignoring wink on channel %d \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Got wink in weird state %u on channel %d \n " ,  ast_channel_state ( ast ) ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATDMF_TA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch  ( p - > whichwink )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  0 : 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " ANI2 set to '%d' and ANI is '%s' \n " ,  ast_channel_caller ( p - > owner ) - > ani2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													S_COR ( ast_channel_caller ( p - > owner ) - > ani . number . valid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_channel_caller ( p - > owner ) - > ani . number . str ,  " " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												snprintf ( p - > dop . dialstr ,  sizeof ( p - > dop . dialstr ) ,  " M*%d%s# " , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_channel_caller ( p - > owner ) - > ani2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													S_COR ( ast_channel_caller ( p - > owner ) - > ani . number . valid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_channel_caller ( p - > owner ) - > ani . number . str ,  " " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_copy_string ( p - > dop . dialstr ,  p - > finaldial ,  sizeof ( p - > dop . dialstr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Received unexpected wink on channel of type ANALOG_SIG_FEATDMF_TA \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > whichwink + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_E911 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FGC_CAMAMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FGC_CAMA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATB : 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-21 20:26:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  ANALOG_SIG_EMWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* FGD MF and EMWINK *Must* wait for wink */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( ! ast_strlen_zero ( p - > dop . dialstr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  analog_dial_digits ( p ,  ANALOG_SUB_REAL ,  & p - > dop ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-28 18:27:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													p - > dop . dialstr [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Sent deferred digit string on channel %d: %s \n " ,  p - > channel ,  p - > dop . dialstr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > dop . dialstr [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Don't know how to handle ring/off hook for signalling %d \n " ,  p - > sig ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_HOOKCOMPLETE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( p - > inalarm )  break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( analog_check_waitingfordt ( p ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										switch  ( mysig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSLS :   /* only interesting for FXS */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSKS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EM_E1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EMWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SFWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ast_strlen_zero ( p - > dop . dialstr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  analog_dial_digits ( p ,  ANALOG_SUB_REAL ,  & p - > dop ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-09-28 18:27:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													p - > dop . dialstr [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Sent deferred digit string on channel %d: %s \n " ,  p - > channel ,  p - > dop . dialstr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > dop . dialstr [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											p - > dop . op  =  ANALOG_DIAL_OP_REPLACE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATDMF_TA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_E911 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FGC_CAMA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FGC_CAMAMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Got hook complete in MF FGD, waiting for wink now on channel %d \n " , p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_POLARITY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*
 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										 *  If  we  get  a  Polarity  Switch  event ,  this  could  be 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  due  to  line  seizure ,  remote  end  connect  or  remote  end  disconnect . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  Check  to  see  if  we  should  change  the  polarity  state  and 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										 *  mark  the  channel  as  UP  or  if  this  is  an  indication 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  of  remote  end  disconnect . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 16:24:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( p - > polarityonanswerdelay  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* check if event is not too soon after OffHook or Answer */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( ast_tvdiff_ms ( ast_tvnow ( ) ,  p - > polaritydelaytv )  >  p - > polarityonanswerdelay )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												switch  ( ast_channel_state ( ast ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												case  AST_STATE_DIALING : 			/*!< Digits (or equivalent) have been dialed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_STATE_RINGING : 			/*!< Remote end is ringing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( p - > answeronpolarityswitch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " Answering on polarity switch! channel %d \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_setstate ( p - > owner ,  AST_STATE_UP ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														p - > polarity  =  POLARITY_REV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( p - > hanguponpolarityswitch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															p - > polaritydelaytv  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " Ignore Answer on polarity switch, channel %d \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												case  AST_STATE_UP : 				/*!< Line is up */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_STATE_RING : 			/*!< Line is ringing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( p - > hanguponpolarityswitch )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " HangingUp on polarity switch! channel %d \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-06 22:03:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_queue_control_data ( ast ,  AST_CONTROL_PVT_CAUSE_CODE ,  cause_code ,  data_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-08-15 17:56:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_channel_hangupcause_hash_set ( ast ,  cause_code ,  data_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_softhangup ( p - > owner ,  AST_SOFTHANGUP_EXPLICIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														p - > polarity  =  POLARITY_IDLE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " Ignore Hangup on polarity switch, channel %d \n " ,  p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_STATE_DOWN : 				/*!< Channel is down and available */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_STATE_RESERVED : 			/*!< Channel is down, but reserved */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_STATE_OFFHOOK : 				/*!< Channel is off hook */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_STATE_BUSY : 				/*!< Line is busy */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_STATE_DIALING_OFFHOOK : 		/*!< Digits (or equivalent) have been dialed while offhook */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_STATE_PRERING : 				/*!< Channel has detected an incoming call and is waiting for ring */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( p - > answeronpolarityswitch  | |  p - > hanguponpolarityswitch )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " Ignoring Polarity switch on channel %d, state %u \n " ,  p - > channel ,  ast_channel_state ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* event is too soon after OffHook or Answer */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												switch  ( ast_channel_state ( ast ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												case  AST_STATE_DIALING : 		/*!< Digits (or equivalent) have been dialed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_STATE_RINGING : 		/*!< Remote end is ringing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( p - > answeronpolarityswitch )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " Polarity switch detected but NOT answering (too close to OffHook event) on channel %d, state %u \n " ,  p - > channel ,  ast_channel_state ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_STATE_UP : 			/*!< Line is up */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												case  AST_STATE_RING : 		/*!< Line is ringing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( p - > hanguponpolarityswitch )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " Polarity switch detected but NOT hanging up (too close to Answer event) on channel %d, state %u \n " ,  p - > channel ,  ast_channel_state ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 16:24:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												default : 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( p - > answeronpolarityswitch  | |  p - > hanguponpolarityswitch )  { 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " Polarity switch detected (too close to previous event) on channel %d, state %u \n " ,  p - > channel ,  ast_channel_state ( ast ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:03:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Added more log_debug information below to provide a better indication of what is going on */ 
							 
						 
					
						
							
								
									
										
										
										
											2014-05-09 22:49:26 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Polarity Reversal event occured - DEBUG 2: channel %d, state %u, pol= %d, aonp= %d, honp= %d, pdelay= %d, tv= % "  PRIi64  " \n " ,  p - > channel ,  ast_channel_state ( ast ) ,  p - > polarity ,  p - > answeronpolarityswitch ,  p - > hanguponpolarityswitch ,  p - > polarityonanswerdelay ,  ast_tvdiff_ms ( ast_tvnow ( ) ,  p - > polaritydelaytv )  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Dunno what to do with event %d on channel %d \n " ,  res ,  p - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  & p - > subs [ idx ] . f ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  ast_frame  * analog_exception ( struct  analog_pvt  * p ,  struct  ast_channel  * ast )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  idx ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  * f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " %s %d \n " ,  __FUNCTION__ ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									idx  =  analog_get_index ( ast ,  p ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( idx  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										idx  =  ANALOG_SUB_REAL ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . frametype  =  AST_FRAME_NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . datalen  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . samples  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . mallocd  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . subclass . integer  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . delivery  =  ast_tv ( 0 , 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . src  =  " dahdi_exception " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ idx ] . f . data . ptr  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! p - > owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* If nobody owns us, absorb the event appropriately, otherwise
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   we  loop  indefinitely .   This  occurs  when ,  during  call  waiting ,  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   other  end  hangs  up  our  channel  so  that  it  no  longer  exists ,  but  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   have  neither  FLASH ' d  nor  ONHOOK ' d  to  signify  our  desire  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   change  to  the  other  channel .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  analog_get_event ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Switch to real if there is one and this isn't something really silly... */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( res  ! =  ANALOG_EVENT_RINGEROFF )  & &  ( res  ! =  ANALOG_EVENT_RINGERON )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											( res  ! =  ANALOG_EVENT_HOOKCOMPLETE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Restoring owner of channel %d on event %d \n " ,  p - > channel ,  res ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_set_new_owner ( p ,  p - > subs [ ANALOG_SUB_REAL ] . owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( p - > owner  & &  ast  ! =  p - > owner )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  Could  this  even  happen ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 *  Possible  deadlock  because  we  do  not  have  the  real - call  lock . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Event %s on %s is not restored owner %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													analog_event2str ( res ) ,  ast_channel_name ( ast ) ,  ast_channel_name ( p - > owner ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-01 20:00:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( p - > owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 21:21:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_queue_unhold ( p - > owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_EVENT_ONHOOK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_set_echocanceller ( p ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p - > owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_verb ( 3 ,  " Channel %s still has call, ringing phone \n " ,  ast_channel_name ( p - > owner ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												analog_ring ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_stop_callwait ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Absorbed %s, but nobody is left!?!? \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_event2str ( res ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											analog_update_conf ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_EVENT_RINGOFFHOOK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_set_echocanceller ( p ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_off_hook ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( p - > owner  & &  ( ast_channel_state ( p - > owner )  = =  AST_STATE_RINGING ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_queue_control ( p - > owner ,  AST_CONTROL_ANSWER ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-15 22:02:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												analog_set_dialing ( p ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_EVENT_HOOKCOMPLETE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_EVENT_RINGERON : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_EVENT_RINGEROFF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Do nothing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_EVENT_WINKFLASH : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											gettimeofday ( & p - > flashtime ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( p - > owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_verb ( 3 ,  " Channel %d flashed to other channel %s \n " ,  p - > channel ,  ast_channel_name ( p - > owner ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ast_channel_state ( p - > owner )  ! =  AST_STATE_UP )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													/* Answer if necessary */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_queue_control ( p - > owner ,  AST_CONTROL_ANSWER ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_setstate ( p - > owner ,  AST_STATE_UP ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_stop_callwait ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-05-24 21:21:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_queue_unhold ( p - > owner ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Absorbed %s, but nobody is left!?!? \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_event2str ( res ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											analog_update_conf ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Don't know how to absorb event %s \n " ,  analog_event2str ( res ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:52:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										f  =  & p - > subs [ idx ] . f ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-01 22:09:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Exception on %d, channel %d \n " ,  ast_channel_fd ( ast ,  0 ) ,  p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* If it's not us, return NULL immediately */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast  ! =  p - > owner )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " We're %s, not %s \n " ,  ast_channel_name ( ast ) ,  ast_channel_name ( p - > owner ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										f  =  & p - > subs [ idx ] . f ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-11 17:34:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									f  =  __analog_handle_event ( p ,  ast ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-11 17:34:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! f )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  char  * name  =  ast_strdupa ( ast_channel_name ( ast ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Tell the CDR this DAHDI device hung up */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_unlock_private ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_unlock ( ast ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_set_hangupsource ( ast ,  name ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_lock ( ast ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_lock_private ( p ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-14 22:38:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  * analog_handle_init_event ( struct  analog_pvt  * i ,  int  event )  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pthread_t  threadid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-03-13 01:12:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_callid  callid  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  callid_created ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " channel (%d) - signaling (%d) - event (%s) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												i - > channel ,  i - > sig ,  analog_event2str ( event ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Handle an event on a given channel for the monitor thread. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( event )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_WINKFLASH : 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 00:47:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ANALOG_EVENT_RINGBEGIN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( i - > sig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSKS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( i - > immediate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( i - > use_callerid  | |  i - > usedistinctiveringdetection )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Can't start PBX immediately, must wait for Caller ID / distinctive ring \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* If we don't care about Caller ID or Distinctive Ring, then there's
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  no  need  to  wait  for  anything  before  accepting  the  call ,  as 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  waiting  will  buy  us  nothing . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  So  if  the  channel  is  configured  for  immediate ,  actually  start  immediately 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  and  get  the  show  on  the  road  as  soon  as  possible .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Disabling ring timeout (previously %d) to begin handling immediately \n " ,  i - > ringt_base ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													analog_set_ringtimeout ( i ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( ISTRUNK ( i )  & &  i - > immediate  & &  ! i - > use_callerid  & &  ! i - > usedistinctiveringdetection ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_RINGOFFHOOK : 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( i - > inalarm )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Got a ring/answer.  What kind of channel are we? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( i - > sig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOKS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  analog_off_hook ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											i - > fxsoffhookstate  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( res  & &  ( errno  = =  EBUSY ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											callid_created  =  ast_callid_threadstorage_auto ( & callid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Cancel VMWI spill */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-10 20:18:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_cancel_cidspill ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( i - > immediate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												analog_set_echocanceller ( i ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* The channel is immediately up.  Start right away */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  analog_play_tone ( i ,  ANALOG_SUB_REAL ,  ANALOG_TONE_RINGTONE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												chan  =  analog_new_ast_channel ( i ,  AST_STATE_RING ,  1 ,  ANALOG_SUB_REAL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												if  ( ! chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Unable to start PBX on channel %d \n " ,  i - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  analog_play_tone ( i ,  ANALOG_SUB_REAL ,  ANALOG_TONE_CONGESTION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( res  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING ,  " Unable to play congestion tone on channel %d \n " ,  i - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Check for callerid, digits, etc */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												chan  =  analog_new_ast_channel ( i ,  AST_STATE_RESERVED ,  0 ,  ANALOG_SUB_REAL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												i - > ss_astchan  =  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( chan )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( analog_has_voicemail ( i ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														res  =  analog_play_tone ( i ,  ANALOG_SUB_REAL ,  ANALOG_TONE_STUTTER ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														res  =  analog_play_tone ( i ,  ANALOG_SUB_REAL ,  ANALOG_TONE_DIALTONE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													if  ( res  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING ,  " Unable to play dialtone on channel %d, do you have defaultzone and loadzone defined? \n " ,  i - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-14 22:38:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( ast_pthread_create_detached ( & threadid ,  NULL ,  __analog_ss_thread ,  i ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING ,  " Unable to start simple switch thread on channel %d \n " ,  i - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														res  =  analog_play_tone ( i ,  ANALOG_SUB_REAL ,  ANALOG_TONE_CONGESTION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( res  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
															ast_log ( LOG_WARNING ,  " Unable to play congestion tone on channel %d \n " ,  i - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
														ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Unable to create channel \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_callid_threadstorage_auto_clean ( callid ,  callid_created ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSKS : 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_set_ringtimeout ( i ,  i - > ringt_base ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Fall through */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EMWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATDMF_TA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_E911 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FGC_CAMA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FGC_CAMAMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EM_E1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SFWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF : 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											callid_created  =  ast_callid_threadstorage_auto ( & callid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Check for callerid, digits, etc */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-03 19:40:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( i - > cid_start  = =  ANALOG_CID_START_POLARITY_IN  | |  i - > cid_start  = =  ANALOG_CID_START_DTMF_NOALERT )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												chan  =  analog_new_ast_channel ( i ,  AST_STATE_PRERING ,  0 ,  ANALOG_SUB_REAL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												chan  =  analog_new_ast_channel ( i ,  AST_STATE_RING ,  0 ,  ANALOG_SUB_REAL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											i - > ss_astchan  =  chan ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Cannot allocate new structure on channel %d \n " ,  i - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( ast_pthread_create_detached ( & threadid ,  NULL ,  __analog_ss_thread ,  i ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Unable to start simple switch thread on channel %d \n " ,  i - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  analog_play_tone ( i ,  ANALOG_SUB_REAL ,  ANALOG_TONE_CONGESTION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Unable to play congestion tone on channel %d \n " ,  i - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_callid_threadstorage_auto_clean ( callid ,  callid_created ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Don't know how to handle ring/answer with signalling %s on channel %d \n " ,  analog_sigtype_to_str ( i - > sig ) ,  i - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  analog_play_tone ( i ,  ANALOG_SUB_REAL ,  ANALOG_TONE_CONGESTION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Unable to play congestion tone on channel %d \n " ,  i - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-14 22:38:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_NOALARM : 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-04 21:10:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_alarm ( i ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-01 13:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_publish_channel_alarm_clear ( i - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_ALARM : 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-04 21:10:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_alarm ( i ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_get_and_handle_alarms ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* fall thru intentionally */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_ONHOOK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Back on hook.  Hang up. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( i - > sig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOGS : 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											i - > fxsoffhookstate  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 23:14:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_start_polarityswitch ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Fall through */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATDMF_TA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_E911 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FGC_CAMA : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FGC_CAMAMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EM_E1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_EMWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATDMF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF_FEATB : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SF : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_SFWINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSKS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_set_echocanceller ( i ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  analog_play_tone ( i ,  ANALOG_SUB_REAL ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_on_hook ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXOKS : 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-14 20:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											i - > fxsoffhookstate  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-23 11:01:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											analog_start_polarityswitch ( i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											analog_set_echocanceller ( i ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Diddle the battery for the zhone */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# ifdef ZHONE_HACK 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_off_hook ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											usleep ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# endif 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  analog_play_tone ( i ,  ANALOG_SUB_REAL ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											analog_on_hook ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Don't know how to handle on hook with signalling %s on channel %d \n " ,  analog_sigtype_to_str ( i - > sig ) ,  i - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  analog_play_tone ( i ,  ANALOG_SUB_REAL ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-14 22:38:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_POLARITY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( i - > sig )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSKS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											callid_created  =  ast_callid_threadstorage_auto ( & callid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											/* We have already got a PR before the channel was
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   created ,  but  it  wasn ' t  handled .  We  need  polarity 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   to  be  REV  for  remote  hangup  detection  to  work . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   At  least  in  Spain  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( i - > hanguponpolarityswitch )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												i - > polarity  =  POLARITY_REV ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( i - > cid_start  = =  ANALOG_CID_START_POLARITY  | |  i - > cid_start  = =  ANALOG_CID_START_POLARITY_IN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												i - > polarity  =  POLARITY_REV ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-20 17:55:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_verb ( 2 ,  " Starting post polarity CID detection on channel %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													i - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												chan  =  analog_new_ast_channel ( i ,  AST_STATE_PRERING ,  0 ,  ANALOG_SUB_REAL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												i - > ss_astchan  =  chan ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Cannot allocate new structure on channel %d \n " ,  i - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ast_pthread_create_detached ( & threadid ,  NULL ,  __analog_ss_thread ,  i ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Unable to start simple switch thread on channel %d \n " ,  i - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-12 20:28:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_callid_threadstorage_auto_clean ( callid ,  callid_created ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-20 17:55:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" handle_init_event detected polarity reversal on non-FXO (ANALOG_SIG_FXS) interface %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												i - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-03 19:40:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ANALOG_EVENT_DTMFCID : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch  ( i - > sig )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSLS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSKS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  ANALOG_SIG_FXSGS : 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											callid_created  =  ast_callid_threadstorage_auto ( & callid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( i - > cid_start  = =  ANALOG_CID_START_DTMF_NOALERT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verb ( 2 ,  " Starting DTMF CID detection on channel %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													i - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												chan  =  analog_new_ast_channel ( i ,  AST_STATE_PRERING ,  0 ,  ANALOG_SUB_REAL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												i - > ss_astchan  =  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Cannot allocate new structure on channel %d \n " ,  i - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ast_pthread_create_detached ( & threadid ,  NULL ,  __analog_ss_thread ,  i ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Unable to start simple switch thread on channel %d \n " ,  i - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-07-12 20:28:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-03 19:40:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2012-06-26 21:45:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_callid_threadstorage_auto_clean ( callid ,  callid_created ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2015-02-20 17:55:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" handle_init_event detected dtmfcid generation event on non-FXO (ANALOG_SIG_FXS) interface %d \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												i - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-03 19:40:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-14 22:38:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  ANALOG_EVENT_REMOVED :  /* destroy channel, will actually do so in do_monitor */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_NOTICE ,  " Got ANALOG_EVENT_REMOVED. Destroying channel %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-11 20:38:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											i - > channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  i - > chan_pvt ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_NEONMWI_ACTIVE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_handle_notify_message ( NULL ,  i ,  - 1 ,  ANALOG_EVENT_NEONMWI_ACTIVE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  ANALOG_EVENT_NEONMWI_INACTIVE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										analog_handle_notify_message ( NULL ,  i ,  - 1 ,  ANALOG_EVENT_NEONMWI_INACTIVE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-14 22:38:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-08-08 20:32:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								struct  analog_pvt  * analog_new ( enum  analog_sigtype  signallingtype ,  void  * private_data )  
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  analog_pvt  * p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p  =  ast_calloc ( 1 ,  sizeof ( * p ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! p )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  p ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > outsigmod  =  ANALOG_SIG_NONE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > sig  =  signallingtype ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > chan_pvt  =  private_data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Some defaults for values */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > cid_start  =  ANALOG_CID_START_RING ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > cid_signalling  =  CID_SIG_BELL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Sub real is assumed to always be alloc'd */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > subs [ ANALOG_SUB_REAL ] . allocd  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-08 23:37:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Delete  the  analog  private  structure . 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-21 18:51:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ since  1.8 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-08 23:37:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  doomed  Analog  private  structure  to  delete . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  analog_delete ( struct  analog_pvt  * doomed )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( doomed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								int  analog_config_complete ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* No call waiting on non FXS channels */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( p - > sig  ! =  ANALOG_SIG_FXOKS )  & &  ( p - > sig  ! =  ANALOG_SIG_FXOLS )  & &  ( p - > sig  ! =  ANALOG_SIG_FXOGS ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										p - > permcallwaiting  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 22:52:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									analog_set_callwaiting ( p ,  p - > permcallwaiting ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  analog_free ( struct  analog_pvt  * p )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_free ( p ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* called while dahdi_pvt is locked in dahdi_fixup */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  analog_fixup ( struct  ast_channel  * oldchan ,  struct  ast_channel  * newchan ,  void  * newp )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  analog_pvt  * new_pvt  =  newp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " New owner for channel %d is %s \n " ,  new_pvt - > channel ,  ast_channel_name ( newchan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( new_pvt - > owner  = =  oldchan )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-20 03:13:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										analog_set_new_owner ( new_pvt ,  newchan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( x  =  0 ;  x  <  3 ;  x + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( new_pvt - > subs [ x ] . owner  = =  oldchan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											new_pvt - > subs [ x ] . owner  =  newchan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-14 23:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:19:51 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									analog_update_conf ( new_pvt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2009-09-10 23:29:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2013-07-01 13:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  analog_publish_dnd_state ( int  channel ,  const  char  * status )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RAII_VAR ( struct  ast_json  * ,  body ,  NULL ,  ast_json_unref ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									RAII_VAR ( struct  ast_str  * ,  dahdichan ,  ast_str_create ( 32 ) ,  ast_free ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! dahdichan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_str_set ( & dahdichan ,  0 ,  " DAHDI/%d " ,  channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									body  =  ast_json_pack ( " {s: s, s: s} " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" Channel " ,  ast_str_buffer ( dahdichan ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" Status " ,  status ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! body )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_manager_publish_event ( " DNDState " ,  EVENT_FLAG_SYSTEM ,  body ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-10 23:29:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  analog_dnd ( struct  analog_pvt  * p ,  int  flag )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( flag  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  p - > dnd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									p - > dnd  =  flag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_verb ( 3 ,  " %s DND on channel %d \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-19 16:49:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											flag  ?  " Enabled "  :  " Disabled " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-10 23:29:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											p - > channel ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2013-07-01 13:16:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									analog_publish_dnd_state ( p - > channel ,  flag  ?  " enabled "  :  " disabled " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-10 23:29:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}