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 > 
							 
						 
					
						
							
								
									
										
										
										
											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 " ) ;