2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2005-09-14 20:46:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Asterisk  - -  An  open  source  telephony  toolkit . 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-14 20:46:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( C )  1999  -  2005 ,  Digium ,  Inc . 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Mark  Spencer  < markster @ digium . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-14 20:46:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  See  http : //www.asterisk.org for more information about
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  Asterisk  project .  Please  do  not  directly  contact 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  any  of  the  maintainers  of  this  project  for  assistance ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  the  project  provides  a  web  site ,  mailing  lists  and  IRC 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  channels  for  your  use . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 *  This  program  is  free  software ,  distributed  under  the  terms  of 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-14 20:46:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  the  GNU  General  Public  License  Version  2.  See  the  LICENSE  file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  at  the  top  of  the  source  tree . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-24 20:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \file
  
						 
					
						
							
								
									
										
										
										
											2005-09-14 20:46:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-24 20:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ brief  Dial  plan  macro  Implementation 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-30 21:18:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ author  Mark  Spencer  < markster @ digium . com > 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 09:23:22 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-06 15:09:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ ingroup  applications 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-07-14 20:28:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*** MODULEINFO
  
						 
					
						
							
								
									
										
										
										
											2017-10-16 11:53:07 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									< defaultenabled > no < / defaultenabled > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< support_level > deprecated < / support_level > 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-14 20:28:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									< replacement > app_stack  ( GoSub ) < / replacement > 
							 
						 
					
						
							
								
									
										
											 
										
											
												policy: Add deprecation and removal versions to modules.
app_meetme is deprecated in 19, to be removed in 21.
app_osplookup is deprecated in 19, to be removed in 21.
chan_alsa is deprecated in 19, to be removed in 21.
chan_mgcp is deprecated in 19, to be removed in 21.
chan_skinny is deprecated in 19, to be removed in 21.
res_pktccops is deprecated in 19, to be removed in 21.
cdr_mysql was deprecated in 1.8, to be removed in 19.
app_mysql was deprecated in 1.8, to be removed in 19.
app_ices was deprecated in 16, to be removed in 19.
app_macro was deprecated in 16, to be removed in 21.
app_fax was deprecated in 16, to be removed in 19.
app_url was deprecated in 16, to be removed in 19.
app_image was deprecated in 16, to be removed in 19.
app_nbscat was deprecated in 16, to be removed in 19.
app_dahdiras was deprecated in 16, to be removed in 19.
cdr_syslog was deprecated in 16, to be removed in 19.
chan_oss was deprecated in 16, to be removed in 19.
chan_phone was deprecated in 16, to be removed in 19.
chan_sip was deprecated in 17, to be removed in 21.
chan_nbs was deprecated in 16, to be removed in 19.
chan_misdn was deprecated in 16, to be removed in 19.
chan_vpb was deprecated in 16, to be removed in 19.
res_config_sqlite was deprecated in 16, to be removed in 19.
res_monitor was deprecated in 16, to be removed in 21.
conf2ael was deprecated in 16, to be removed in 19.
muted was deprecated in 16, to be removed in 19.
ASTERISK-29548
ASTERISK-29549
ASTERISK-29550
ASTERISK-29551
ASTERISK-29552
ASTERISK-29553
ASTERISK-29554
ASTERISK-29555
ASTERISK-29557
ASTERISK-29558
ASTERISK-29559
ASTERISK-29560
ASTERISK-29561
ASTERISK-29562
ASTERISK-29563
ASTERISK-29564
ASTERISK-29565
ASTERISK-29566
ASTERISK-29567
ASTERISK-29568
ASTERISK-29569
ASTERISK-29570
ASTERISK-29571
ASTERISK-29572
ASTERISK-29573
ASTERISK-29574
Change-Id: Ic3bee31a10d42c4b3bbc913d893f7b2a28a27131
											 
										 
										
											2021-08-11 08:15:16 -03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									< deprecated_in > 16 < / deprecated_in > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< removed_in > 21 < / removed_in > 
							 
						 
					
						
							
								
									
										
										
										
											2011-11-10 23:21:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * * */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-14 20:28:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-07 18:54:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-21 06:02:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/file.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/channel.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/pbx.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/module.h" 
  
						 
					
						
							
								
									
										
										
										
											2018-05-04 14:47:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/extconf.h" 
  
						 
					
						
							
								
									
										
										
										
											2005-04-21 06:02:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/config.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/utils.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/lock.h" 
  
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/app.h" 
  
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-05 18:46:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*** DOCUMENTATION
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< application  name = " Macro "  language = " en_US " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Macro  Implementation . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " name "  required = " true " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< para > The  name  of  the  macro < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " args " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< argument  name = " arg1 "  required = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< argument  name = " arg2 "  multiple = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > Executes  a  macro  using  the  context  macro - < replaceable > name < / replaceable > , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											jumping  to  the  < literal > s < / literal >  extension  of  that  context  and  executing  each  step , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											then  returning  when  the  steps  end . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > The  calling  extension ,  context ,  and  priority  are  stored  in  < variable > MACRO_EXTEN < / variable > , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< variable > MACRO_CONTEXT < / variable >  and  < variable > MACRO_PRIORITY < / variable >  respectively .  Arguments 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											become  < variable > ARG1 < / variable > ,  < variable > ARG2 < / variable > ,  etc  in  the  macro  context . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > If  you  Goto  out  of  the  Macro  context ,  the  Macro  will  terminate  and  control  will  be  returned 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											at  the  location  of  the  Goto . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > If  < variable > MACRO_OFFSET < / variable >  is  set  at  termination ,  Macro  will  attempt  to  continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											at  priority  MACRO_OFFSET  +  N  +  1  if  such  a  step  exists ,  and  N  +  1  otherwise . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< warning > < para > Because  of  the  way  Macro  is  implemented  ( it  executes  the  priorities  contained  within 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											it  via  sub - engine ) ,  and  a  fixed  per - thread  memory  stack  allowance ,  macros  are  limited  to  7  levels 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											of  nesting  ( macro  calling  macro  calling  macro ,  etc . ) ;  It  may  be  possible  that  stack - intensive 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											applications  in  deeply  nested  macros  could  cause  asterisk  to  crash  earlier  than  this  limit . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											It  is  advised  that  if  you  need  to  deeply  nest  macro  calls ,  that  you  use  the  Gosub  application 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-30 21:04:41 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											( now  allows  arguments  like  a  Macro )  with  explicit  Return ( )  calls  instead . < / para > < / warning > 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-18 14:45:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											< warning > < para > Use  of  the  application  < literal > WaitExten < / literal >  within  a  macro  will  not  function 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											as  expected .  Please  use  the  < literal > Read < / literal >  application  in  order  to  read  DTMF  from  a  channel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											currently  executing  a  macro . < / para > < / warning > 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-05 18:46:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										< / description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " application " > MacroExit < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " application " > Goto < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " application " > Gosub < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< / application > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< application  name = " MacroIf "  language = " en_US " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Conditional  Macro  implementation . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< syntax  argsep = " ? " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " expr "  required = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " destination "  required = " true "  argsep = " : " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< argument  name = " macroiftrue "  required = " true " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< argument  name = " macroiftrue "  required = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< argument  name = " arg1 "  multiple = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< / argument > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< argument  name = " macroiffalse " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< argument  name = " macroiffalse "  required = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< argument  name = " arg1 "  multiple = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< / argument > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > Executes  macro  defined  in  < replaceable > macroiftrue < / replaceable >  if 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< replaceable > expr < / replaceable >  is  true  ( otherwise  < replaceable > macroiffalse < / replaceable > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  provided ) < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > Arguments  and  return  values  as  in  application  Macro ( ) < / para > 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-18 14:45:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											< xi : include  xpointer = " xpointer(/docs/application[@name='Macro']/description/warning[2]) "  / > 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-05 18:46:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										< / description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " application " > GotoIf < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " application " > GosubIf < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " function " > IF < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< / application > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< application  name = " MacroExclusive "  language = " en_US " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Exclusive  Macro  Implementation . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " name "  required = " true " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< para > The  name  of  the  macro < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " arg1 "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " arg2 "  multiple = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > Executes  macro  defined  in  the  context  macro - < replaceable > name < / replaceable > . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Only  one  call  at  a  time  may  run  the  macro .  ( we ' ll  wait  if  another  call  is  busy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											executing  in  the  Macro ) < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > Arguments  and  return  values  as  in  application  Macro ( ) < / para > 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-18 14:45:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											< xi : include  xpointer = " xpointer(/docs/application[@name='Macro']/description/warning[2]) "  / > 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-05 18:46:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										< / description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " application " > Macro < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< / application > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< application  name = " MacroExit "  language = " en_US " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Exit  from  Macro . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< syntax  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > Causes  the  currently  running  macro  to  exit  as  if  it  had 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ended  normally  by  running  out  of  priorities  to  execute . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											If  used  outside  a  macro ,  will  likely  cause  unexpected  behavior . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " application " > Macro < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< / application > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# define MAX_ARGS 80 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-07 05:42:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* special result value used to force macro exit */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define MACRO_EXIT_RESULT 1024 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  char  * app  =  " Macro " ;  
						 
					
						
							
								
									
										
										
										
											2004-11-22 23:41:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * if_app  =  " MacroIf " ;  
						 
					
						
							
								
									
										
										
										
											2006-08-14 03:24:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * exclusive_app  =  " MacroExclusive " ;  
						 
					
						
							
								
									
										
										
										
											2005-01-07 05:42:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * exit_app  =  " MacroExit " ;  
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 21:18:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  macro_fixup ( void  * data ,  struct  ast_channel  * old_chan ,  struct  ast_channel  * new_chan ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-18 17:18:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  struct  ast_datastore_info  macro_ds_info  =  {  
						 
					
						
							
								
									
										
										
										
											2008-12-17 21:18:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									. type  =  " MACRO " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									. chan_fixup  =  macro_fixup , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  macro_fixup ( void  * data ,  struct  ast_channel  * old_chan ,  struct  ast_channel  * new_chan )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  varname [ 10 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( new_chan ,  " MACRO_DEPTH " ,  " 0 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( new_chan ,  " MACRO_CONTEXT " ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( new_chan ,  " MACRO_EXTEN " ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( new_chan ,  " MACRO_PRIORITY " ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( new_chan ,  " MACRO_OFFSET " ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  1 ;  i  <  100 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										snprintf ( varname ,  sizeof ( varname ) ,  " ARG%d " ,  i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( pbx_builtin_getvar_helper ( new_chan ,  varname ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Kill all levels of arguments */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pbx_builtin_setvar_helper ( new_chan ,  varname ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-05-04 14:47:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_exten  * find_matching_priority ( struct  ast_context  * c ,  const  char  * exten ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  priority ,  const  char  * callerid ,  int  iter ,  int  * had_error ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_exten  * e ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_context  * c2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:51:42 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  idx ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-05-04 14:47:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( iter  > =  AST_PBX_MAX_STACK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( * had_error ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* had_error  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " Potential infinite loop detected, will not recurse further. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( e = ast_walk_context_extensions ( c ,  NULL ) ;  e ;  e = ast_walk_context_extensions ( c ,  e ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_extension_match ( ast_get_extension_name ( e ) ,  exten ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  needmatch  =  ast_get_extension_matchcid ( e ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( needmatch  & &  ast_extension_match ( ast_get_extension_cidmatch ( e ) ,  callerid ) )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												( ! needmatch ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* This is the matching extension we want */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												struct  ast_exten  * p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												for  ( p = ast_walk_extension_priorities ( e ,  NULL ) ;  p ;  p = ast_walk_extension_priorities ( e ,  p ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( priority  ! =  ast_get_extension_priority ( p ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* No match; run through includes */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-07-14 14:51:42 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( idx  =  0 ;  idx  <  ast_context_includes_count ( c ) ;  idx + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  struct  ast_include  * i  =  ast_context_includes_get ( c ,  idx ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( c2 = ast_walk_contexts ( NULL ) ;  c2 ;  c2 = ast_walk_contexts ( c2 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! strcmp ( ast_get_context_name ( c2 ) ,  ast_get_include_name ( i ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-04 14:47:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												e  =  find_matching_priority ( c2 ,  exten ,  priority ,  callerid ,  iter  +  1 ,  had_error ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( e ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  e ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-21 21:13:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  _macro_exec ( struct  ast_channel  * chan ,  const  char  * data ,  int  exclusive )  
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-12-03 19:25:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * s ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * tmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * cur ,  * rest ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * macro ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  fullmacro [ 80 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  varname [ 80 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 22:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  runningapp [ 80 ] ,  runningdata [ 1024 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * oldargs [ MAX_ARGS  +  1 ]  =  {  NULL ,  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  argc ,  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res = 0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  oldexten [ 256 ] = " " ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  oldpriority ,  gosub_level  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 20:39:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  pc [ 80 ] ,  depthc [ 12 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-10 23:49:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  oldcontext [ AST_MAX_CONTEXT ]  =  " " ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-07 15:35:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * inhangupc ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-17 15:48:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  offset ,  depth  =  0 ,  maxdepth  =  7 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  setmacrocontext = 0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 21:18:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  autoloopflag ,  inhangup  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-29 18:53:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_str  * tmp_subst  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 09:51:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * my_macro_exten  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * save_macro_exten ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * save_macro_context ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * save_macro_priority ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * save_macro_offset ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												main/cdrs: Preserve context/extension when executing a Macro or GoSub
The context/extension in a CDR is generally considered the destination of a
call. When looking at a 2-party call CDR, users will typically be presented
with the following:
context    exten      channel     dest_channel app  data
default    1000       SIP/8675309 SIP/1000     Dial SIP/1000,,20
However, if the Dial actually takes place in a Macro, the current behaviour
in 12 will result in the following CDR:
context    exten      channel     dest_channel app  data
macro-dial s          SIP/8675309 SIP/1000     Dial SIP/1000,,20
The same is true of a GoSub:
context    exten      channel     dest_channel app  data
subs       dial_stuff SIP/8675309 SIP/1000     Dial SIP/1000,,20
This generally makes the context/exten fields less than useful.
It isn't hard to preserve these values in the CDR state machine; however, we
need to have something that informs us when a channel is executing a
subroutine. Prior to this patch, there isn't anything that does this.
This patch solves this problem by adding a new channel flag,
AST_FLAG_SUBROUTINE_EXEC. This flag is set on a channel when it executes a
Macro or a GoSub. The CDR engine looks for this value when updating a Party A
snapshot; if the flag is present, we don't override the context/exten on the
main CDR object. In a funny quirk, executing a hangup handler must *not* abide
by this logic, as the endbeforehexten logic assumes that the user wants to see
data that occurs in hangup logic, which includes those subroutines. Since
those execute outside of a typical Dial operation (and will typically have
their own dedicated CDR anyway), this is unlikely to cause any heartburn.
Review: https://reviewboard.asterisk.org/r/3962/
ASTERISK-24254 #close
Reported by: tm1000, Tony Lewis
Tested by: Tony Lewis
........
Merged revisions 422718 from http://svn.asterisk.org/svn/asterisk/branches/12
........
Merged revisions 422719 from http://svn.asterisk.org/svn/asterisk/branches/13
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@422720 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-09-05 22:04:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  save_in_subroutine ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 21:18:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_datastore  * macro_store  =  ast_channel_datastore_find ( chan ,  & macro_ds_info ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-04 14:47:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  had_infinite_include_error  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-10-16 11:53:07 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									static  int  deprecation_notice  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-29 18:53:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-26 19:48:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( data ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-31 01:10:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Macro() requires arguments. See  \" core show application macro \"  for help. \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-19 18:19:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2004-11-22 23:41:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-16 11:53:07 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! deprecation_notice )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										deprecation_notice  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Macro() is deprecated and will be removed from a future version of Asterisk. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Dialplan should be updated to use Gosub instead. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 21:18:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( macro_store )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 21:28:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ( macro_store  =  ast_datastore_alloc ( & macro_ds_info ,  NULL ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 21:18:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Unable to allocate new datastore. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Just the existence of this datastore is enough. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										macro_store - > inheritance  =  DATASTORE_INHERIT_FOREVER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_datastore_add ( chan ,  macro_store ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  while  ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-17 15:48:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* does the user want a deeper rabbit hole? */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-30 19:21:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( s  =  pbx_builtin_getvar_helper ( chan ,  " MACRO_RECURSION " ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-10 19:20:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sscanf ( s ,  " %30d " ,  & maxdepth ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-30 19:21:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 09:23:22 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 20:39:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Count how many levels deep the rabbit hole goes */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-30 19:21:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( s  =  pbx_builtin_getvar_helper ( chan ,  " MACRO_DEPTH " ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-10 19:20:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sscanf ( s ,  " %30d " ,  & depth ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-30 19:21:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 09:23:22 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-07 15:35:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Used for detecting whether to return when a Macro is called from another Macro after hangup */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( strcmp ( ast_channel_exten ( chan ) ,  " h " )  = =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-07 15:35:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  " MACRO_IN_HANGUP " ,  " 1 " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 09:23:22 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-30 19:21:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( inhangupc  =  pbx_builtin_getvar_helper ( chan ,  " MACRO_IN_HANGUP " ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-10 19:20:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										sscanf ( inhangupc ,  " %30d " ,  & inhangup ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-30 19:21:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-07 15:35:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-17 15:48:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( depth  > =  maxdepth )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 20:39:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Macro():  possible infinite loop detected.  Returning early. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( depthc ,  sizeof ( depthc ) ,  " %d " ,  depth  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-19 18:19:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tmp  =  ast_strdupa ( data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									rest  =  tmp ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-23 19:51:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									macro  =  strsep ( & rest ,  " , " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-26 19:48:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( macro ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Invalid macro name specified \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-14 03:24:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									snprintf ( fullmacro ,  sizeof ( fullmacro ) ,  " macro-%s " ,  macro ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 09:51:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* first search for the macro */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ast_context_find ( fullmacro ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " No such context '%s' for macro '%s'. Was called by %s@%s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fullmacro ,  macro ,  ast_channel_exten ( chan ) ,  ast_channel_context ( chan ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* now search for the right extension */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_exists_extension ( chan ,  fullmacro ,  " s " ,  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										S_COR ( ast_channel_caller ( chan ) - > id . number . valid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_channel_caller ( chan ) - > id . number . str ,  NULL ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* We have a normal macro */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										my_macro_exten  =  " s " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ast_exists_extension ( chan ,  fullmacro ,  " ~~s~~ " ,  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										S_COR ( ast_channel_caller ( chan ) - > id . number . valid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_channel_caller ( chan ) - > id . number . str ,  NULL ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* We have an AEL generated macro */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										my_macro_exten  =  " ~~s~~ " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* do we have a valid exten? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! my_macro_exten )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Context '%s' for macro '%s' lacks 's' extension, priority 1 \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fullmacro ,  macro ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-14 03:24:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If we are to run the macro exclusively, take the mutex */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( exclusive )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Locking macrolock for '%s' \n " ,  fullmacro ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-14 03:24:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_autoservice_start ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_context_lockmacro ( fullmacro ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Failed to lock macro '%s' as in-use \n " ,  fullmacro ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_autoservice_stop ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_autoservice_stop ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-29 18:53:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( tmp_subst  =  ast_str_create ( 16 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Save old info */ 
							 
						 
					
						
							
								
									
										
											 
										
											
												main/cdrs: Preserve context/extension when executing a Macro or GoSub
The context/extension in a CDR is generally considered the destination of a
call. When looking at a 2-party call CDR, users will typically be presented
with the following:
context    exten      channel     dest_channel app  data
default    1000       SIP/8675309 SIP/1000     Dial SIP/1000,,20
However, if the Dial actually takes place in a Macro, the current behaviour
in 12 will result in the following CDR:
context    exten      channel     dest_channel app  data
macro-dial s          SIP/8675309 SIP/1000     Dial SIP/1000,,20
The same is true of a GoSub:
context    exten      channel     dest_channel app  data
subs       dial_stuff SIP/8675309 SIP/1000     Dial SIP/1000,,20
This generally makes the context/exten fields less than useful.
It isn't hard to preserve these values in the CDR state machine; however, we
need to have something that informs us when a channel is executing a
subroutine. Prior to this patch, there isn't anything that does this.
This patch solves this problem by adding a new channel flag,
AST_FLAG_SUBROUTINE_EXEC. This flag is set on a channel when it executes a
Macro or a GoSub. The CDR engine looks for this value when updating a Party A
snapshot; if the flag is present, we don't override the context/exten on the
main CDR object. In a funny quirk, executing a hangup handler must *not* abide
by this logic, as the endbeforehexten logic assumes that the user wants to see
data that occurs in hangup logic, which includes those subroutines. Since
those execute outside of a typical Dial operation (and will typically have
their own dedicated CDR anyway), this is unlikely to cause any heartburn.
Review: https://reviewboard.asterisk.org/r/3962/
ASTERISK-24254 #close
Reported by: tm1000, Tony Lewis
Tested by: Tony Lewis
........
Merged revisions 422718 from http://svn.asterisk.org/svn/asterisk/branches/12
........
Merged revisions 422719 from http://svn.asterisk.org/svn/asterisk/branches/13
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@422720 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-09-05 22:04:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									oldpriority  =  ast_channel_priority ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_copy_string ( oldexten ,  ast_channel_exten ( chan ) ,  sizeof ( oldexten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_copy_string ( oldcontext ,  ast_channel_context ( chan ) ,  sizeof ( oldcontext ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( ast_channel_macrocontext ( chan ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_macrocontext_set ( chan ,  ast_channel_context ( chan ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_macroexten_set ( chan ,  ast_channel_exten ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_macropriority_set ( chan ,  ast_channel_priority ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										setmacrocontext = 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									argc  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Save old macro variables */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-13 18:38:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									save_macro_exten  =  ast_strdup ( pbx_builtin_getvar_helper ( chan ,  " MACRO_EXTEN " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " MACRO_EXTEN " ,  oldexten ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-13 18:38:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									save_macro_context  =  ast_strdup ( pbx_builtin_getvar_helper ( chan ,  " MACRO_CONTEXT " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " MACRO_CONTEXT " ,  oldcontext ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-13 18:38:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									save_macro_priority  =  ast_strdup ( pbx_builtin_getvar_helper ( chan ,  " MACRO_PRIORITY " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									snprintf ( pc ,  sizeof ( pc ) ,  " %d " ,  oldpriority ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " MACRO_PRIORITY " ,  pc ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 09:23:22 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-13 18:38:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									save_macro_offset  =  ast_strdup ( pbx_builtin_getvar_helper ( chan ,  " MACRO_OFFSET " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " MACRO_OFFSET " ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-29 18:53:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " MACRO_DEPTH " ,  depthc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												main/cdrs: Preserve context/extension when executing a Macro or GoSub
The context/extension in a CDR is generally considered the destination of a
call. When looking at a 2-party call CDR, users will typically be presented
with the following:
context    exten      channel     dest_channel app  data
default    1000       SIP/8675309 SIP/1000     Dial SIP/1000,,20
However, if the Dial actually takes place in a Macro, the current behaviour
in 12 will result in the following CDR:
context    exten      channel     dest_channel app  data
macro-dial s          SIP/8675309 SIP/1000     Dial SIP/1000,,20
The same is true of a GoSub:
context    exten      channel     dest_channel app  data
subs       dial_stuff SIP/8675309 SIP/1000     Dial SIP/1000,,20
This generally makes the context/exten fields less than useful.
It isn't hard to preserve these values in the CDR state machine; however, we
need to have something that informs us when a channel is executing a
subroutine. Prior to this patch, there isn't anything that does this.
This patch solves this problem by adding a new channel flag,
AST_FLAG_SUBROUTINE_EXEC. This flag is set on a channel when it executes a
Macro or a GoSub. The CDR engine looks for this value when updating a Party A
snapshot; if the flag is present, we don't override the context/exten on the
main CDR object. In a funny quirk, executing a hangup handler must *not* abide
by this logic, as the endbeforehexten logic assumes that the user wants to see
data that occurs in hangup logic, which includes those subroutines. Since
those execute outside of a typical Dial operation (and will typically have
their own dedicated CDR anyway), this is unlikely to cause any heartburn.
Review: https://reviewboard.asterisk.org/r/3962/
ASTERISK-24254 #close
Reported by: tm1000, Tony Lewis
Tested by: Tony Lewis
........
Merged revisions 422718 from http://svn.asterisk.org/svn/asterisk/branches/12
........
Merged revisions 422719 from http://svn.asterisk.org/svn/asterisk/branches/13
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@422720 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-09-05 22:04:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									save_in_subroutine  =  ast_test_flag ( ast_channel_flags ( chan ) ,  AST_FLAG_SUBROUTINE_EXEC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_set_flag ( ast_channel_flags ( chan ) ,  AST_FLAG_SUBROUTINE_EXEC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Setup environment for new run */ 
							 
						 
					
						
							
								
									
										
										
										
											2016-08-17 09:51:17 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_exten_set ( chan ,  my_macro_exten ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_context_set ( chan ,  fullmacro ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_priority_set ( chan ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-23 19:51:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while ( ( cur  =  strsep ( & rest ,  " , " ) )  & &  ( argc  <  MAX_ARGS ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 14:45:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  char  * argp ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  		/* Save copy of old arguments if we're overwriting some, otherwise
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   	let  them  pass  through  to  the  other  macro  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  		snprintf ( varname ,  sizeof ( varname ) ,  " ARG%d " ,  argc ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 14:45:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( argp  =  pbx_builtin_getvar_helper ( chan ,  varname ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											oldargs [ argc ]  =  ast_strdup ( argp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-30 19:21:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  varname ,  cur ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										argc + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-13 18:20:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									autoloopflag  =  ast_test_flag ( ast_channel_flags ( chan ) ,  AST_FLAG_IN_AUTOLOOP ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_set_flag ( ast_channel_flags ( chan ) ,  AST_FLAG_IN_AUTOLOOP ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-13 18:17:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( ast_exists_extension ( chan ,  ast_channel_context ( chan ) ,  ast_channel_exten ( chan ) ,  ast_channel_priority ( chan ) , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										S_COR ( ast_channel_caller ( chan ) - > id . number . valid ,  ast_channel_caller ( chan ) - > id . number . str ,  NULL ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 22:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  ast_context  * c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_exten  * e ; 
							 
						 
					
						
							
								
									
										
										
											
												This commits the performance mods that give the priority processing engine in the pbx, a 25-30% speed boost. The two updates used, are, first, to merge the ast_exists_extension() and the ast_spawn_extension() where they are called sequentially in a loop in the code, into a slightly upgraded version of ast_spawn_extension(), with a few extra args; and, second, I modified the substitute_variables_helper_full, so it zeroes out the byte after the evaluated string instead of demanding you pre-zero the buffer; I also went thru the code and removed the code that zeroed this buffer before every call to the substitute_variables_helper_full. The first fix provides about a 9% speedup, and the second the rest. These figures come from the 'PIPS' benchmark I describe in blogs, conf. reports, etc.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@88166 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-11-01 22:26:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  foundx ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 17:16:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										runningapp [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										runningdata [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 22:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* What application will execute? */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 22:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_rdlock_contexts ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Failed to lock contexts list \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( c  =  ast_walk_contexts ( NULL ) ,  e  =  NULL ;  c ;  c  =  ast_walk_contexts ( c ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! strcmp ( ast_get_context_name ( c ) ,  ast_channel_context ( chan ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 22:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ast_rdlock_context ( c ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING ,  " Unable to lock context? \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														e  =  find_matching_priority ( c ,  ast_channel_exten ( chan ) ,  ast_channel_priority ( chan ) , 
							 
						 
					
						
							
								
									
										
										
										
											2018-05-04 14:47:25 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															S_COR ( ast_channel_caller ( chan ) - > id . number . valid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_channel_caller ( chan ) - > id . number . str ,  NULL ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															0 ,  & had_infinite_include_error ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 17:16:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( e )  {  /* This will only be undefined for pbx_realtime, which is majorly broken. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_copy_string ( runningapp ,  ast_get_extension_app ( e ) ,  sizeof ( runningapp ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															ast_copy_string ( runningdata ,  ast_get_extension_app_data ( e ) ,  sizeof ( runningdata ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 22:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_unlock_context ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 22:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_unlock_contexts ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 20:39:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Reset the macro depth, if it was changed in the last iteration */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  " MACRO_DEPTH " ,  depthc ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										res  =  ast_spawn_extension ( chan ,  ast_channel_context ( chan ) ,  ast_channel_exten ( chan ) ,  ast_channel_priority ( chan ) , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											S_COR ( ast_channel_caller ( chan ) - > id . number . valid ,  ast_channel_caller ( chan ) - > id . number . str ,  NULL ) , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											& foundx ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Something bad happened, or a hangup has been requested. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( ( res  > =  ' 0 ' )  & &  ( res  < =  ' 9 ' ) )  | |  ( ( res  > =  ' A ' )  & &  ( res  < =  ' F ' ) )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										    	( res  = =  ' * ' )  | |  ( res  = =  ' # ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Just return result as to the previous application as if it had been dialed */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Oooh, got something to jump out with ('%c')! \n " ,  res ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-05 17:20:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											case  MACRO_EXIT_RESULT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default : 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 2 ,  " Spawn extension (%s,%s,%d) exited non-zero on '%s' in macro '%s' \n " ,  ast_channel_context ( chan ) ,  ast_channel_exten ( chan ) ,  ast_channel_priority ( chan ) ,  ast_channel_name ( chan ) ,  macro ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_verb ( 2 ,  " Spawn extension (%s, %s, %d) exited non-zero on '%s' in macro '%s' \n " ,  ast_channel_context ( chan ) ,  ast_channel_exten ( chan ) ,  ast_channel_priority ( chan ) ,  ast_channel_name ( chan ) ,  macro ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Executed application: %s \n " ,  runningapp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 22:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( runningapp ,  " GOSUB " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											gosub_level + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Incrementing gosub_level \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 22:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( runningapp ,  " GOSUBIF " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-21 21:13:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											char  * cond ,  * app_arg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											char  * app2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-29 18:53:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_str_substitute_variables ( & tmp_subst ,  0 ,  chan ,  runningdata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											app2  =  ast_str_buffer ( tmp_subst ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											cond  =  strsep ( & app2 ,  " ? " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 14:45:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											app_arg  =  strsep ( & app2 ,  " : " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( pbx_checkcondition ( cond ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 14:45:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ! ast_strlen_zero ( app_arg ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													gosub_level + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Incrementing gosub_level \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! ast_strlen_zero ( app2 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													gosub_level + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Incrementing gosub_level \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 22:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( runningapp ,  " RETURN " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											gosub_level - - ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Decrementing gosub_level \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 22:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( runningapp ,  " STACKPOP " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											gosub_level - - ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Decrementing gosub_level \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 22:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strncasecmp ( runningapp ,  " EXEC " ,  4 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Must evaluate args to find actual app */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-29 18:53:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											char  * tmp2 ,  * tmp3  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_str_substitute_variables ( & tmp_subst ,  0 ,  chan ,  runningdata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tmp2  =  ast_str_buffer ( tmp_subst ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 22:40:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! strcasecmp ( runningapp ,  " EXECIF " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-21 21:13:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ( tmp3  =  strchr ( tmp2 ,  ' | ' ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													* tmp3 + +  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-29 18:53:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! pbx_checkcondition ( tmp2 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													tmp3  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-29 18:53:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												tmp3  =  tmp2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-29 18:53:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-29 18:53:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( tmp3 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Last app: %s \n " ,  tmp3 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-29 18:53:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( tmp3  & &  ! strncasecmp ( tmp3 ,  " GOSUB " ,  5 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												gosub_level + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Incrementing gosub_level \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( tmp3  & &  ! strncasecmp ( tmp3 ,  " RETURN " ,  6 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												gosub_level - - ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Decrementing gosub_level \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( tmp3  & &  ! strncasecmp ( tmp3 ,  " STACKPOP " ,  8 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												gosub_level - - ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Decrementing gosub_level \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( gosub_level  = =  0  & &  strcasecmp ( ast_channel_context ( chan ) ,  fullmacro ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-01-09 22:15:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_verb ( 2 ,  " Channel '%s' jumping out of macro '%s' \n " ,  ast_channel_name ( chan ) ,  macro ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-08 14:23:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* don't stop executing extensions when we're in "h" */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-01 15:39:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_check_hangup ( chan )  & &  ! inhangup )  { 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-13 18:17:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Extension %s, macroexten %s, priority %d returned normally even though call was hung up \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_exten ( chan ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_macroexten ( chan ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_priority ( chan ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											goto  out ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_priority_set ( chan ,  ast_channel_priority ( chan )  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  	} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									out : 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 21:18:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Don't let the channel change now. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 20:39:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Reset the depth back to what it was when the routine was entered (like if we called Macro recursively) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( depthc ,  sizeof ( depthc ) ,  " %d " ,  depth ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 21:18:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " MACRO_DEPTH " ,  depthc ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-03-13 18:20:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_set2_flag ( ast_channel_flags ( chan ) ,  autoloopflag ,  AST_FLAG_IN_AUTOLOOP ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												main/cdrs: Preserve context/extension when executing a Macro or GoSub
The context/extension in a CDR is generally considered the destination of a
call. When looking at a 2-party call CDR, users will typically be presented
with the following:
context    exten      channel     dest_channel app  data
default    1000       SIP/8675309 SIP/1000     Dial SIP/1000,,20
However, if the Dial actually takes place in a Macro, the current behaviour
in 12 will result in the following CDR:
context    exten      channel     dest_channel app  data
macro-dial s          SIP/8675309 SIP/1000     Dial SIP/1000,,20
The same is true of a GoSub:
context    exten      channel     dest_channel app  data
subs       dial_stuff SIP/8675309 SIP/1000     Dial SIP/1000,,20
This generally makes the context/exten fields less than useful.
It isn't hard to preserve these values in the CDR state machine; however, we
need to have something that informs us when a channel is executing a
subroutine. Prior to this patch, there isn't anything that does this.
This patch solves this problem by adding a new channel flag,
AST_FLAG_SUBROUTINE_EXEC. This flag is set on a channel when it executes a
Macro or a GoSub. The CDR engine looks for this value when updating a Party A
snapshot; if the flag is present, we don't override the context/exten on the
main CDR object. In a funny quirk, executing a hangup handler must *not* abide
by this logic, as the endbeforehexten logic assumes that the user wants to see
data that occurs in hangup logic, which includes those subroutines. Since
those execute outside of a typical Dial operation (and will typically have
their own dedicated CDR anyway), this is unlikely to cause any heartburn.
Review: https://reviewboard.asterisk.org/r/3962/
ASTERISK-24254 #close
Reported by: tm1000, Tony Lewis
Tested by: Tony Lewis
........
Merged revisions 422718 from http://svn.asterisk.org/svn/asterisk/branches/12
........
Merged revisions 422719 from http://svn.asterisk.org/svn/asterisk/branches/13
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@422720 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2014-09-05 22:04:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_set2_flag ( ast_channel_flags ( chan ) ,  save_in_subroutine ,  AST_FLAG_SUBROUTINE_EXEC ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 20:39:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-05 17:20:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  	for  ( x  =  1 ;  x  <  argc ;  x + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  		/* Restore old arguments and delete ours */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										snprintf ( varname ,  sizeof ( varname ) ,  " ARG%d " ,  x ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-13 18:17:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  varname ,  oldargs [ x ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_free ( oldargs [ x ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  	} 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Restore macro variables */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 21:18:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " MACRO_EXTEN " ,  save_macro_exten ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " MACRO_CONTEXT " ,  save_macro_context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " MACRO_PRIORITY " ,  save_macro_priority ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-13 18:17:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_free ( save_macro_exten ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( save_macro_context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_free ( save_macro_priority ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-05 17:20:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 21:18:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( setmacrocontext )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_macrocontext_set ( chan ,  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_macroexten_set ( chan ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_macropriority_set ( chan ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2015-01-13 18:17:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! strcasecmp ( ast_channel_context ( chan ) ,  fullmacro ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										& &  ! ( ast_channel_softhangup_internal_flag ( chan )  &  AST_SOFTHANGUP_ASYNCGOTO ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:42:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  char  * offsets ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								  		/* If we're leaving the macro normally, restore original information */ 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_priority_set ( chan ,  oldpriority ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_context_set ( chan ,  oldcontext ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_exten_set ( chan ,  oldexten ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:42:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( offsets  =  pbx_builtin_getvar_helper ( chan ,  " MACRO_OFFSET " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Handle macro offset if it's set by checking the availability of step n + offset + 1, otherwise continue
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											normally  if  there  is  any  problem  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( sscanf ( offsets ,  " %30d " ,  & offset )  = =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-13 17:27:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ast_exists_extension ( chan ,  ast_channel_context ( chan ) ,  ast_channel_exten ( chan ) , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_channel_priority ( chan )  +  offset  +  1 , 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-29 16:52:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													S_COR ( ast_channel_caller ( chan ) - > id . number . valid ,  ast_channel_caller ( chan ) - > id . number . str ,  NULL ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2012-02-20 23:43:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_channel_priority_set ( chan ,  ast_channel_priority ( chan )  +  offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-03-12 06:00:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 21:18:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " MACRO_OFFSET " ,  save_macro_offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2015-01-13 18:17:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_free ( save_macro_offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-14 03:24:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Unlock the macro */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( exclusive )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Unlocking macrolock for '%s' \n " ,  fullmacro ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-14 03:24:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_context_unlockmacro ( fullmacro ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_ERROR ,  " Failed to unlock macro '%s' - that isn't good \n " ,  fullmacro ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-17 21:18:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-29 18:53:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_free ( tmp_subst ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 02:11:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 18:45:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-21 21:13:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  macro_exec ( struct  ast_channel  * chan ,  const  char  * data )  
						 
					
						
							
								
									
										
										
										
											2006-08-14 03:24:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-08-14 03:34:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  _macro_exec ( chan ,  data ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-14 03:24:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-21 21:13:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  macroexclusive_exec ( struct  ast_channel  * chan ,  const  char  * data )  
						 
					
						
							
								
									
										
										
										
											2006-08-14 03:24:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-08-14 03:34:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  _macro_exec ( chan ,  data ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-14 03:24:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 09:23:22 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  macroif_exec ( struct  ast_channel  * chan ,  const  char  * data )  
						 
					
						
							
								
									
										
										
										
											2004-11-22 23:41:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * expr  =  NULL ,  * label_a  =  NULL ,  * label_b  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2012-07-31 20:21:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									expr  =  ast_strdupa ( data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-19 18:19:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( label_a  =  strchr ( expr ,  ' ? ' ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* label_a  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										label_a + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( label_b  =  strchr ( label_a ,  ' : ' ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* label_b  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											label_b + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-05 14:47:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( pbx_checkcondition ( expr ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-30 14:53:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  macro_exec ( chan ,  label_a ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2017-12-22 09:23:22 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else  if  ( label_b ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-30 14:53:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  macro_exec ( chan ,  label_b ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-19 18:19:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Invalid Syntax. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-11-22 23:41:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2017-12-22 09:23:22 -05:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-21 21:13:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  macro_exit_exec ( struct  ast_channel  * chan ,  const  char  * data )  
						 
					
						
							
								
									
										
										
										
											2005-01-07 05:42:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  MACRO_EXIT_RESULT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 02:11:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  unload_module ( void )  
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-10-18 22:52:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  ast_unregister_application ( if_app ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  | =  ast_unregister_application ( exit_app ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  | =  ast_unregister_application ( app ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-14 03:24:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  | =  ast_unregister_application ( exclusive_app ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-18 22:52:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 02:11:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  load_module ( void )  
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-10-18 22:52:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-05 18:46:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  ast_register_application_xml ( exit_app ,  macro_exit_exec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  | =  ast_register_application_xml ( if_app ,  macroif_exec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  | =  ast_register_application_xml ( exclusive_app ,  macroexclusive_exec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  | =  ast_register_application_xml ( app ,  macro_exec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-18 22:52:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2017-10-16 11:53:07 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								AST_MODULE_INFO_STANDARD_DEPRECATED ( ASTERISK_GPL_KEY ,  " Extension Macros " ) ;