2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Asterisk  - -  An  open  source  telephony  toolkit . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( C )  2019 ,  CyCore  Systems ,  Inc 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Seán  C  McCord  < scm @ cycoresys . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  See  http : //www.asterisk.org for more information about
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  Asterisk  project .  Please  do  not  directly  contact 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  any  of  the  maintainers  of  this  project  for  assistance ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  project  provides  a  web  site ,  mailing  lists  and  IRC 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  channels  for  your  use . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  This  program  is  free  software ,  distributed  under  the  terms  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  GNU  General  Public  License  Version  2.  See  the  LICENSE  file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  at  the  top  of  the  source  tree . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \file
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  AudioSocket  application  - -  transmit  and  receive  audio  through  a  TCP  socket 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ author  Seán  C  McCord  < scm @ cycoresys . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ ingroup  applications 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*** MODULEINFO
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< depend > res_audiosocket < / depend > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< support_level > extended < / support_level > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "errno.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <uuid/uuid.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/file.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/module.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/channel.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/app.h" 
  
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/pbx.h" 
  
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/res_audiosocket.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/utils.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/format_cache.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define AST_MODULE "app_audiosocket" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define AUDIOSOCKET_CONFIG "audiosocket.conf" 
  
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define MAX_WAIT_TIMEOUT_MSEC 2000 
  
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*** DOCUMENTATION
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< application  name = " AudioSocket "  language = " en_US " > 
							 
						 
					
						
							
								
									
										
										
										
											2025-01-23 16:35:58 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										< since > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< version > 18.0 .0 < / version > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / since > 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										< synopsis > 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											Transmit  and  receive  PCM  audio  between  a  channel  and  a  TCP  socket  server . 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										< / synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " uuid "  required = " true " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< para > UUID  is  the  universally - unique  identifier  of  the  call  for  the  audio  socket  service .   This  ID  must  conform  to  the  string  form  of  a  standard  UUID . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " service "  required = " true " > 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												< para > Service  is  the  name  or  IP  address  and  port  number  of  the  audio  socket  service  to  which  this  call  should  be  connected .   This  should  be  in  the  form  host : port ,  such  as  myserver : 9019.  IPv6  addresses  can  be  specified  in  square  brackets ,  like  [ : : 1 ] : 9019 < / para > 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< description > 
							 
						 
					
						
							
								
									
										
										
										
											2025-02-28 08:47:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											< para > Connects  to  the  given  TCP  server ,  then  transmits  channel  audio  as  16 - bit ,  8 KHz  mono  PCM  over  that  socket  ( other  codecs  available  via  the  channel  driver  interface ) .  In  turn ,  PCM  audio  is  received  from  the  socket  and  sent  to  the  channel .   Only  audio  frames  and  DTMF  frames  will  be  transmitted . < / para > 
							 
						 
					
						
							
								
									
										
										
										
											2023-11-09 16:26:46 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											< para > Protocol  is  specified  at  https : //docs.asterisk.org/Configuration/Channel-Drivers/AudioSocket/</para>
 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-09 09:02:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											< para > This  application  does  not  automatically  answer  and  should  generally  be  preceded  by  an  application  such  as  Answer ( )  or  Progress ( ) . < / para > 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										< / description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< / application > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  char  app [ ]  =  " AudioSocket " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  audiosocket_run ( struct  ast_channel  * chan ,  const  char  * id ,  const  int  svc ,  const  char  * server ) ;  
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  audiosocket_exec ( struct  ast_channel  * chan ,  const  char  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * parse ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_format  * readFormat ,  * writeFormat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * chanName ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_DECLARE_APP_ARGS ( args , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( idStr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( server ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  s  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uuid_t  uu ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									chanName  =  ast_channel_name ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Parse and validate arguments */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parse  =  ast_strdupa ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_STANDARD_APP_ARGS ( args ,  parse ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( args . idStr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " UUID is required \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( uuid_parse ( args . idStr ,  uu ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Failed to parse UUID '%s' \n " ,  args . idStr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( s  =  ast_audiosocket_connect ( args . server ,  chan ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* The res module will already output a log message, so another is not needed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Save current channel audio format and force to linear PCM. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									writeFormat  =  ao2_bump ( ast_channel_writeformat ( chan ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									readFormat  =  ao2_bump ( ast_channel_readformat ( chan ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_set_write_format ( chan ,  ast_format_slin ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Failed to set write format to SLINEAR for channel '%s' \n " ,  chanName ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  end ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ast_set_read_format ( chan ,  ast_format_slin ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Failed to set read format to SLINEAR for channel '%s' \n " ,  chanName ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  end ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Only a requested hangup or socket closure from the remote end will
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   return  a  0  value  ( normal  exit ) .  All  other  events  that  disrupt  an 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   active  connection  are  treated  as  errors  for  now  ( non - zero ) .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  audiosocket_run ( chan ,  args . idStr ,  s ,  args . server ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								end :  
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Restore previous formats and close the connection */ 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( ast_set_write_format ( chan ,  writeFormat ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Failed to restore write format for channel '%s' \n " ,  chanName ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_set_read_format ( chan ,  readFormat ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Failed to restore read format for channel '%s' \n " ,  chanName ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_ref ( writeFormat ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_ref ( readFormat ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									close ( s ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  audiosocket_run ( struct  ast_channel  * chan ,  const  char  * id ,  int  svc ,  const  char  * server )  
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * chanName ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * targetChan ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  ms  =  MAX_WAIT_TIMEOUT_MSEC ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  outfd  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  * f ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  hangup ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! chan  | |  ast_channel_state ( chan )  ! =  AST_STATE_UP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Channel is %s \n " ,  chan  ?  " not answered "  :  " missing " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_audiosocket_init ( svc ,  id ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2025-04-09 09:02:27 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Failed to initialize AudioSocket \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									chanName  =  ast_channel_name ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Timeout is hard-coded currently, could be made into an
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   argument  if  needed ,  but  2  seconds  seems  like  a  realistic 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   time  range  to  give .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										targetChan  =  ast_waitfor_nandfds ( & chan ,  1 ,  & svc ,  1 ,  NULL ,  & outfd ,  & ms ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ms  =  MAX_WAIT_TIMEOUT_MSEC ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( targetChan )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Receive frame from connected channel. */ 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											f  =  ast_read ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! f )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Failed to receive frame from channel '%s' connected to AudioSocket server '%s' " ,  chanName ,  server ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2025-02-28 08:47:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( f - > frametype  = =  AST_FRAME_VOICE  | |  f - > frametype  = =  AST_FRAME_DTMF )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Send audio frame or DTMF frame to audiosocket */ 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												if  ( ast_audiosocket_send_frame ( svc ,  f ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Failed to forward frame from channel '%s' to AudioSocket server '%s' \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														chanName ,  server ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( outfd  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Receive audio frame from audiosocket. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f  =  ast_audiosocket_receive_frame_with_hangup ( svc ,  & hangup ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hangup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Graceful termination, no frame to free. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( ! f )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Failed to receive frame from AudioSocket server '%s' " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													"  connected to channel '%s' \n " ,  server ,  chanName ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Send audio frame to connected channel. */ 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  ( ast_write ( chan ,  f ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Failed to forward frame from AudioSocket server '%s' to channel '%s' \n " ,  server ,  chanName ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 21:36:11 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Neither the channel nor audio socket had activity
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   before  timeout .  Assume  connection  was  lost .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " Reached timeout after %d ms of no activity on AudioSocket connection between '%s' and '%s' \n " ,  MAX_WAIT_TIMEOUT_MSEC ,  chanName ,  server ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-07-17 20:47:50 -04:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  unload_module ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ast_unregister_application ( app ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  load_module ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ast_register_application_xml ( app ,  audiosocket_exec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								AST_MODULE_INFO (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ASTERISK_GPL_KEY , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_MODFLAG_LOAD_ORDER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									" AudioSocket Application " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. support_level  =  AST_MODULE_SUPPORT_EXTENDED , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. load  = 	load_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. unload  =  unload_module , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. load_pri  =  AST_MODPRI_CHANNEL_DRIVER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. requires  =  " res_audiosocket " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ;