2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2005-09-14 20:46:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Asterisk  - -  An  open  source  telephony  toolkit . 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( C )  1999  -  2008 ,  Digium ,  Inc . 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-31 13:32:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Mark  Spencer  < markster @ digium . com > 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											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 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +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 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-19 22:09:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ brief  Routines  implementing  call  features  as  call  pickup ,  parking  and  transfer 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-30 21:18:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ author  Mark  Spencer  < markster @ digium . com >  
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-07 18:54:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ASTERISK_FILE_VERSION ( __FILE__ ,  " $Revision$ " )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/_private.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-06 22:12:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <pthread.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <sys/time.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <sys/signal.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <netinet/in.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-21 06:02:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/lock.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/file.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/channel.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/pbx.h" 
  
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/causes.h" 
  
						 
					
						
							
								
									
										
										
										
											2005-04-21 06:02:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/module.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/translate.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/app.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/say.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/features.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/musiconhold.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/config.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/cli.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/manager.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/utils.h" 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  "asterisk/adsi.h" 
  
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/devicestate.h" 
  
						 
					
						
							
								
									
										
										
										
											2005-11-08 04:02:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/monitor.h" 
  
						 
					
						
							
								
									
										
										
										
											2007-11-30 21:19:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/audiohook.h" 
  
						 
					
						
							
								
									
										
										
										
											2008-03-01 01:30:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/global_datastores.h" 
  
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "asterisk/astobj2.h" 
  
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-01 21:10:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*** DOCUMENTATION
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< application  name = " Bridge "  language = " en_US " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Bridge  two  channels . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " channel "  required = " true " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< para > The  current  channel  is  bridged  to  the  specified  < replaceable > channel < / replaceable > . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " options " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< optionlist > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< option  name = " p " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														< para > Play  a  courtesy  tone  to  < replaceable > channel < / replaceable > . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< / option > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< / optionlist > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > Allows  the  ability  to  bridge  two  channels  via  the  dialplan . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > This  application  sets  the  following  channel  variable  upon  completion : < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< variablelist > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< variable  name = " BRIDGERESULT " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< para > The  result  of  the  bridge  attempt  as  a  text  string . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< value  name = " SUCCESS "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< value  name = " FAILURE "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< value  name = " LOOP "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< value  name = " NONEXISTENT "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< value  name = " INCOMPATIBLE "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< / variable > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / variablelist > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< / application > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< application  name = " ParkedCall "  language = " en_US " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Answer  a  parked  call . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " exten "  required = " true "  / > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > Used  to  connect  to  a  parked  call .  This  application  is  always 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											registered  internally  and  does  not  need  to  be  explicitly  added 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											into  the  dialplan ,  although  you  should  include  the  < literal > parkedcalls < / literal > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											context .  If  no  extension  is  provided ,  then  the  first  available 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parked  call  will  be  acquired . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / description > 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-05 14:37:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										< see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " application " > Park < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " application " > ParkAndAnnounce < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / see - also > 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-01 21:10:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									< / application > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									< application  name = " Park "  language = " en_US " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											Park  yourself . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / synopsis > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " timeout " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< para > A  custom  parking  timeout  for  this  parked  call . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " return_context " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< para > The  context  to  return  the  call  to  after  it  times  out . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " return_exten " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< para > The  extension  to  return  the  call  to  after  it  times  out . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " return_priority " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< para > The  priority  to  return  the  call  to  after  it  times  out . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< parameter  name = " options " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< para > A  list  of  options  for  this  parked  call . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< optionlist > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< option  name = " r " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														< para > Send  ringing  instead  of  MOH  to  the  parked  call . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< / option > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< option  name = " R " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														< para > Randomize  the  selection  of  a  parking  space . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< / option > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< option  name = " s " > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														< para > Silence  announcement  of  the  parking  space  number . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													< / option > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												< / optionlist > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< / parameter > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / syntax > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< description > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > Used  to  park  yourself  ( typically  in  combination  with  a  supervised 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											transfer  to  know  the  parking  space ) .  This  application  is  always 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											registered  internally  and  does  not  need  to  be  explicitly  added 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											into  the  dialplan ,  although  you  should  include  the  < literal > parkedcalls < / literal > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											context  ( or  the  context  specified  in  < filename > features . conf < / filename > ) . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< para > If  you  set  the  < variable > PARKINGEXTEN < / variable >  variable  to  an  extension  in  your 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parking  context ,  Park ( )  will  park  the  call  on  that  extension ,  unless 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											it  already  exists .  In  that  case ,  execution  will  continue  at  next  priority . < / para > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / description > 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-05 14:37:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										< see - also > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " application " > ParkAndAnnounce < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											< ref  type = " application " > ParkedCall < / ref > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										< / see - also > 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-01 21:10:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									< / application > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-02-02 19:37:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define DEFAULT_PARK_TIME 45000 
  
						 
					
						
							
								
									
										
										
										
											2004-08-01 01:38:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define DEFAULT_TRANSFER_DIGIT_TIMEOUT 3000 
  
						 
					
						
							
								
									
										
										
										
											2008-10-30 16:38:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define DEFAULT_FEATURE_DIGIT_TIMEOUT 2000 
  
						 
					
						
							
								
									
										
										
										
											2006-05-23 18:23:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER 15000 
  
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define DEFAULT_PARKINGLOT "default"			 /*!< Default parking lot */ 
  
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define DEFAULT_ATXFER_DROP_CALL 0 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define DEFAULT_ATXFER_LOOP_DELAY 10000 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define DEFAULT_ATXFER_CALLBACK_RETRIES 2 
  
						 
					
						
							
								
									
										
										
										
											2003-02-02 19:37:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define AST_MAX_WATCHERS 256 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								struct  feature_group_exten  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_ENTRY ( feature_group_exten )  entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_DECLARE_STRING_FIELDS ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_STRING_FIELD ( exten ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_call_feature  * feature ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  feature_group  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_ENTRY ( feature_group )  entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_DECLARE_STRING_FIELDS ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_STRING_FIELD ( gname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_HEAD_NOLOCK ( ,  feature_group_exten )  features ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  AST_RWLIST_HEAD_STATIC ( feature_groups ,  feature_group ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								static  char  * parkedcall  =  " ParkedCall " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-21 07:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  pickup_ext [ AST_MAX_EXTENSION ] ;                  /*!< Call pickup extension */  
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Description of one parked call, added to a list while active, then removed.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									The  list  belongs  to  a  parkinglot  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  parkeduser  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan ;                    /*!< Parking channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  timeval  start ;                        /*!< Time the parking started */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  parkingnum ;                              /*!< Parking lot */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  parkingexten [ AST_MAX_EXTENSION ] ;        /*!< If set beforehand, parking extension used for this call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  context [ AST_MAX_CONTEXT ] ;               /*!< Where to go if our parking time expires */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  exten [ AST_MAX_EXTENSION ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  priority ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  parkingtime ;                             /*!< Maximum length in parking lot before return */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  notquiteyet ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  peername [ 1024 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unsigned  char  moh_trys ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_parkinglot  * parkinglot ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_ENTRY ( parkeduser )  list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Structure for parking lots which are put in a container. */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  ast_parkinglot  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  name [ AST_MAX_CONTEXT ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  parking_con [ AST_MAX_EXTENSION ] ; 		/*!< Context for which parking is made accessible */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  parking_con_dial [ AST_MAX_EXTENSION ] ; 	/*!< Context for dialback for parking (KLUDGE) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  parking_start ; 				/*!< First available extension for parking */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  parking_stop ; 				/*!< Last available extension for parking */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  parking_offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  parkfindnext ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  parkingtime ; 				/*!< Default parking time */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  mohclass [ MAX_MUSICCLASS ] ;                   /*!< Music class used for parking */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  parkaddhints ;                                /*!< Add parking hints automatically */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  parkedcalltransfers ;                         /*!< Enable DTMF based transfers on bridge when picking up parked calls */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  parkedcallreparking ;                         /*!< Enable DTMF based parking on bridge when picking up parked calls */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_HEAD ( parkinglot_parklist ,  parkeduser )  parkings ;  /*!< List of active parkings in this parkinglot */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief The list of parking lots configured. Always at least one  - the default parking lot */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ao2_container  * parkinglots ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  ast_parkinglot  * default_parkinglot ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								char  parking_ext [ AST_MAX_EXTENSION ] ;             /*!< Extension you type to park the call */  
						 
					
						
							
								
									
										
										
										
											2006-06-21 07:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  courtesytone [ 256 ] ;                              /*!< Courtesy tone */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  parkedplay  =  0 ;                                  /*!< Who to play the courtesy tone to */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  xfersound [ 256 ] ;                                 /*!< Call transfer sound */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  xferfailsound [ 256 ] ;                             /*!< Call transfer failure sound */  
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-13 23:58:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  adsipark ;  
						 
					
						
							
								
									
										
										
										
											2004-09-15 19:49:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-13 23:58:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  transferdigittimeout ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  featuredigittimeout ;  
						 
					
						
							
								
									
										
										
										
											2006-11-01 00:07:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  comebacktoorigin  =  1 ;  
						 
					
						
							
								
									
										
										
										
											2004-08-01 01:38:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-23 18:23:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  atxfernoanswertimeout ;  
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  unsigned  int  atxferdropcall ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  unsigned  int  atxferloopdelay ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  unsigned  int  atxfercallbackretries ;  
						 
					
						
							
								
									
										
										
										
											2006-05-23 18:23:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * registrar  =  " features " ; 		   /*!< Registrar for operations */  
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-09 09:07:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* module and CLI command definitions */  
						 
					
						
							
								
									
										
										
										
											2008-10-06 23:08:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * parkcall  =  PARK_APP_NAME ;  
						 
					
						
							
								
									
										
										
										
											2004-08-03 06:31:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-09 09:07:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_app  * monitor_app  =  NULL ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  monitor_ok  =  1 ;  
						 
					
						
							
								
									
										
										
										
											2004-09-17 03:49:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-30 21:19:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_app  * mixmonitor_app  =  NULL ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  mixmonitor_ok  =  1 ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_app  * stopmixmonitor_app  =  NULL ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  stopmixmonitor_ok  =  1 ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  pthread_t  parking_thread ;  
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* Forward declarations */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_parkinglot  * parkinglot_addref ( struct  ast_parkinglot  * parkinglot ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  parkinglot_unref ( struct  ast_parkinglot  * parkinglot ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  parkinglot_destroy ( void  * obj ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  manage_parkinglot ( struct  ast_parkinglot  * curlot ,  fd_set  * rfds ,  fd_set  * efds ,  fd_set  * nrfds ,  fd_set  * nefds ,  int  * fs ,  int  * max ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  ast_parkinglot  * find_parkinglot ( const  char  * name ) ;  
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:08:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  char  * ast_parking_ext ( void )  
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  parking_ext ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:08:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								const  char  * ast_pickup_ext ( void )  
						 
					
						
							
								
									
										
										
										
											2003-04-09 04:00:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  pickup_ext ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								struct  ast_bridge_thread_obj   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_bridge_config  bconfig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * peer ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									unsigned  int  return_to_pbx : 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  parkinglot_hash_cb ( const  void  * obj ,  const  int  flags )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  struct  ast_parkinglot  * parkinglot  =  obj ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-15 04:25:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ast_str_case_hash ( parkinglot - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2007-03-30 14:37:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-25 01:01:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  parkinglot_cmp_cb ( void  * obj ,  void  * arg ,  int  flags )  
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_parkinglot  * parkinglot  =  obj ,  * parkinglot2  =  arg ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-15 04:25:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 17:47:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ! strcasecmp ( parkinglot - > name ,  parkinglot2 - > name )  ?  CMP_MATCH  |  CMP_STOP  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2007-03-30 14:37:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  store  context ,  extension  and  priority  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  chan ,  context ,  ext ,  pri 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2006-04-17 04:31:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  set_c_e_p ( struct  ast_channel  * chan ,  const  char  * context ,  const  char  * ext ,  int  pri )  
						 
					
						
							
								
									
										
										
										
											2006-04-16 18:49:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-04-17 04:31:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_copy_string ( chan - > context ,  context ,  sizeof ( chan - > context ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 18:49:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_copy_string ( chan - > exten ,  ext ,  sizeof ( chan - > exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									chan - > priority  =  pri ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Check  goto  on  transfer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  chan 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Check  if  channel  has  ' GOTO_ON_BLINDXFR '  set ,  if  not  exit . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  When  found  make  sure  the  types  are  compatible .  Check  if  channel  is  valid 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  if  so  start  the  new  channel  else  hangup  the  call .  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2005-04-22 02:55:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  check_goto_on_transfer ( struct  ast_channel  * chan )   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * xferchan ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-03 19:25:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * val  =  pbx_builtin_getvar_helper ( chan ,  " GOTO_ON_BLINDXFR " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * x ,  * goto_on_transfer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  * f ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-22 02:55:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-10 13:22:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( val ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									goto_on_transfer  =  ast_strdupa ( val ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-29 17:57:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( xferchan  =  ast_channel_alloc ( 0 ,  AST_STATE_DOWN ,  0 ,  0 ,  " " ,  " " ,  " " ,  0 ,  " %s " ,  chan - > name ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-10 13:22:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( x  =  goto_on_transfer ;  x  & &  * x ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( * x  = =  ' ^ ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											* x  =  ' | ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Make formats okay */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									xferchan - > readformat  =  chan - > readformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									xferchan - > writeformat  =  chan - > writeformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_masquerade ( xferchan ,  chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_parseable_goto ( xferchan ,  goto_on_transfer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									xferchan - > _state  =  AST_STATE_UP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_clear_flag ( xferchan ,  AST_FLAGS_ALL ) ; 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									xferchan - > _softhangup  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( f  =  ast_read ( xferchan ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										f  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_pbx_start ( xferchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_hangup ( xferchan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-22 02:55:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-02-27 17:31:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_channel  * ast_feature_request_and_dial ( struct  ast_channel  * caller ,  struct  ast_channel  * transferee ,  const  char  * type ,  int  format ,  void  * data ,  int  timeout ,  int  * outstate ,  const  char  * cid_num ,  const  char  * cid_name ,  int  igncallerstate ,  const  char  * language ) ;  
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  bridge  the  call  
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  data  thread  bridge . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Set  Last  Data  for  respective  channels ,  reset  cdr  for  channels 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bridge  call ,  check  if  we ' re  going  back  to  dialplan 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  if  not  hangup  both  legs  of  the  call 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  * ast_bridge_call_thread ( void  * data )   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_bridge_thread_obj  * tobj  =  data ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-06 21:00:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tobj - > chan - > appl  =  ! tobj - > return_to_pbx  ?  " Transferred Call "  :  " ManagerBridge " ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 23:20:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tobj - > chan - > data  =  tobj - > peer - > name ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tobj - > peer - > appl  =  ! tobj - > return_to_pbx  ?  " Transferred Call "  :  " ManagerBridge " ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 23:20:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tobj - > peer - > data  =  tobj - > chan - > name ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_bridge_call ( tobj - > peer ,  tobj - > chan ,  & tobj - > bconfig ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( tobj - > return_to_pbx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ast_check_hangup ( tobj - > peer ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_VERBOSE ,  " putting peer %s into PBX again \n " ,  tobj - > peer - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  ast_pbx_start ( tobj - > peer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( res  ! =  AST_PBX_SUCCESS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " FAILED continuing PBX on peer %s \n " ,  tobj - > peer - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( tobj - > peer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ast_check_hangup ( tobj - > chan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_VERBOSE ,  " putting chan %s into PBX again \n " ,  tobj - > chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  ast_pbx_start ( tobj - > chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( res  ! =  AST_PBX_SUCCESS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " FAILED continuing PBX on chan %s \n " ,  tobj - > chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( tobj - > chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_hangup ( tobj - > chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_hangup ( tobj - > peer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_free ( tobj ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  create  thread  for  the  parked  call 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  data 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Create  thread  and  attributes ,  call  ast_bridge_call_thread 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  ast_bridge_call_thread_launch ( void  * data )   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pthread_t  thread ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pthread_attr_t  attr ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 00:16:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  sched_param  sched ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 00:16:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pthread_attr_init ( & attr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pthread_attr_setdetachstate ( & attr ,  PTHREAD_CREATE_DETACHED ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-09 00:16:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_pthread_create ( & thread ,  & attr , ast_bridge_call_thread ,  data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pthread_attr_destroy ( & attr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									memset ( & sched ,  0 ,  sizeof ( sched ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pthread_setschedparam ( thread ,  SCHED_RR ,  & sched ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Announce  call  parking  by  ADSI 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  chan  . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  parkingexten  . 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Create  message  to  show  for  ADSI ,  display  message . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  on  success . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  on  failure . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  adsi_announce_park ( struct  ast_channel  * chan ,  char  * parkingexten )  
						 
					
						
							
								
									
										
										
										
											2004-09-15 19:49:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  justify [ 5 ]  =  { ADSI_JUST_CENT ,  ADSI_JUST_CENT ,  ADSI_JUST_CENT ,  ADSI_JUST_CENT } ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 21:01:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  tmp [ 256 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 18:55:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * message [ 5 ]  =  { NULL ,  NULL ,  NULL ,  NULL ,  NULL } ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-09-15 19:49:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									snprintf ( tmp ,  sizeof ( tmp ) ,  " Parked on %s " ,  parkingexten ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 18:55:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									message [ 0 ]  =  tmp ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-20 04:34:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  ast_adsi_load_session ( chan ,  NULL ,  0 ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 23:20:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res  = =  - 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-09-15 19:49:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-20 04:34:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  ast_adsi_print ( chan ,  message ,  justify ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-09-15 19:49:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief Find parking lot name from channel */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  const  char  * findparkinglotname ( struct  ast_channel  * chan )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * temp ,  * parkinglot  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Check if the channel has a parking lot */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ast_strlen_zero ( chan - > parkinglot ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										parkinglot  =  chan - > parkinglot ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Channel variables override everything */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ( temp   =  pbx_builtin_getvar_helper ( chan ,  " PARKINGLOT " ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  temp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  parkinglot ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief Notify metermaids that we've changed an extension */  
						 
					
						
							
								
									
										
										
										
											2007-08-10 16:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  notify_metermaids ( const  char  * exten ,  char  * context ,  enum  ast_device_state  state )  
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2007-08-10 16:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 4 ,  " Notification of state change to metermaids %s@%s \n  to state '%s' " ,  
							 
						 
					
						
							
								
									
										
										
										
											2008-11-04 18:47:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										exten ,  context ,  ast_devstate2str ( state ) ) ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-10 16:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_devstate_changed ( state ,  " park:%s@%s " ,  exten ,  context ) ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief metermaids callback from devicestate.c */  
						 
					
						
							
								
									
										
										
										
											2007-02-13 22:02:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  enum  ast_device_state  metermaidstate ( const  char  * data )  
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2007-07-08 13:22:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * context ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * exten ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-08 13:22:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									context  =  ast_strdupa ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									exten  =  strsep ( & context ,  " @ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! context ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-08 13:22:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  AST_DEVICE_INVALID ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 4 ,  " Checking state of exten %s in context %s \n " ,  exten ,  context ) ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-08 13:22:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ast_exists_extension ( NULL ,  context ,  exten ,  1 ,  NULL ) ) 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  AST_DEVICE_NOT_INUSE ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-08 13:22:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  AST_DEVICE_INUSE ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! Options to pass to ast_park_call_full */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								enum  ast_park_call_options  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*! Provide ringing to the parked caller instead of music on hold */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_PARK_OPT_RINGING  =    ( 1  < <  0 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*! Randomly choose a parking spot for the caller instead of choosing
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *   the  first  one  that  is  available .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_PARK_OPT_RANDOMIZE  =  ( 1  < <  1 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 17:53:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/*! Do not announce the parking number */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_PARK_OPT_SILENCE  =  ( 1  < <  2 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  ast_park_call_args  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*! How long to wait in the parking lot before the call gets sent back
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *   to  the  specified  return  extension  ( or  a  best  guess  at  where  it  came 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *   from  if  not  explicitly  specified ) .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  timeout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/*! An output parameter to store the parking space where the parked caller
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *   was  placed .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  * extout ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * orig_chan_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * return_con ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * return_ext ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  return_pri ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									uint32_t  flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* Park a call */  
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  ast_park_call_full ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ,   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_park_call_args  * args ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  parkeduser  * pu ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:26:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  i ,  x  =  - 1 ,  parking_range ,  parkingnum_copy ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-03 06:31:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_context  * con ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-06 17:50:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * parkinglotname  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * parkingexten ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_parkinglot  * parkinglot  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-21 22:09:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2008-06-06 17:50:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( peer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										parkinglotname  =  findparkinglotname ( peer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( parkinglotname )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( option_debug ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_DEBUG ,  " Found chanvar Parkinglot: %s \n " ,  parkinglotname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										parkinglot  =  find_parkinglot ( parkinglotname ) ; 	
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! parkinglot ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										parkinglot  =  default_parkinglot ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									parkinglot_addref ( parkinglot ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( option_debug ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_DEBUG ,  " Parkinglot: %s \n " ,  parkinglot - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Allocate memory for parking data */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( pu  =  ast_calloc ( 1 ,  sizeof ( * pu ) ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										parkinglot_unref ( parkinglot ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-21 07:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Lock parking list */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_LIST_LOCK ( & parkinglot - > parkings ) ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Check for channel variable PARKINGEXTEN */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parkingexten  =  pbx_builtin_getvar_helper ( chan ,  " PARKINGEXTEN " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ast_strlen_zero ( parkingexten ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-12 23:08:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/*!\note The API forces us to specify a numeric parking slot, even
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  though  the  architecture  would  tend  to  support  non - numeric  extensions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  ( as  are  possible  with  SIP ,  for  example ) .   Hence ,  we  enforce  that 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  limitation  here .   If  extout  was  not  numeric ,  we  could  permit 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  arbitrary  non - numeric  extensions . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( sscanf ( parkingexten ,  " %d " ,  & x )  ! =  1  | |  x  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											AST_LIST_UNLOCK ( & parkinglot - > parkings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parkinglot_unref ( parkinglot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            free ( pu ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            ast_log ( LOG_WARNING ,  " PARKINGEXTEN does not indicate a valid parking slot: '%s'. \n " ,  parkingexten ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  1 ;    /* Continue execution if possible */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        snprintf ( pu - > parkingexten ,  sizeof ( pu - > parkingexten ) ,  " %d " ,  x ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_exists_extension ( NULL ,  parkinglot - > parking_con ,  pu - > parkingexten ,  1 ,  NULL ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AST_LIST_UNLOCK ( & parkinglot - > parkings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parkinglot_unref ( parkinglot ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_free ( pu ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Requested parking extension already exists: %s@%s \n " ,  parkingexten ,  parkinglot - > parking_con ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-04 22:57:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  1 ; 	/* Continue execution if possible */ 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  parkeduser  * cur  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Select parking space within range */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										parking_range  =  parkinglot - > parking_stop  -  parkinglot - > parking_start  +  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_test_flag ( args ,  AST_PARK_OPT_RANDOMIZE ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											start  =  ast_random ( )  %  ( parkinglot - > parking_stop  -  parkinglot - > parking_start  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											start  =  parkinglot - > parking_start ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( i  =  start ;  1 ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( i  = =  parkinglot - > parking_stop  +  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												i  =  parkinglot - > parking_start  -  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AST_LIST_TRAVERSE ( & parkinglot - > parkings ,  cur ,  list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( cur - > parkingnum  = =  i )  { 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! cur  | |  i  = =  start  -  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												x  =  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-27 03:58:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( i  = =  start  -  1  & &  cur )  { 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " No more parking spaces \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_free ( pu ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AST_LIST_UNLOCK ( & parkinglot - > parkings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parkinglot_unref ( parkinglot ) ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Set pointer for next parking */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( parkinglot - > parkfindnext )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parkinglot - > parking_offset  =  x  -  parkinglot - > parking_start  +  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-12 23:08:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										snprintf ( pu - > parkingexten ,  sizeof ( pu - > parkingexten ) ,  " %d " ,  x ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									chan - > appl  =  " Parked Call " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									chan - > data  =  NULL ;  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pu - > chan  =  chan ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2006-07-19 20:44:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Put the parked channel on hold if we have two different channels */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( chan  ! =  peer )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_test_flag ( args ,  AST_PARK_OPT_RINGING ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_indicate ( pu - > chan ,  AST_CONTROL_RINGING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_indicate_data ( pu - > chan ,  AST_CONTROL_HOLD ,  
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												S_OR ( parkinglot - > mohclass ,  NULL ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												! ast_strlen_zero ( parkinglot - > mohclass )  ?  strlen ( parkinglot - > mohclass )  +  1  :  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-19 20:44:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pu - > start  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pu - > parkingnum  =  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									pu - > parkinglot  =  parkinglot ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pu - > parkingtime  =  ( args - > timeout  >  0 )  ?  args - > timeout  :  parkinglot - > parkingtime ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:26:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									parkingnum_copy  =  pu - > parkingnum ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( args - > extout ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* ( args - > extout )  =  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-26 17:26:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( peer )  
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_copy_string ( pu - > peername ,  peer - > name ,  sizeof ( pu - > peername ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Remember what had been dialed, so that if the parking
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   expires ,  we  try  to  come  back  to  the  same  place  */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_copy_string ( pu - > context ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										S_OR ( args - > return_con ,  S_OR ( chan - > macrocontext ,  chan - > context ) ) ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sizeof ( pu - > context ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_copy_string ( pu - > exten ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										S_OR ( args - > return_ext ,  S_OR ( chan - > macroexten ,  chan - > exten ) ) ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sizeof ( pu - > exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pu - > priority  =  pu - > priority  ?  pu - > priority  :  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										( chan - > macropriority  ?  chan - > macropriority  :  chan - > priority ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_LIST_INSERT_TAIL ( & parkinglot - > parkings ,  pu ,  list ) ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* If parking a channel directly, don't quiet yet get parking running on it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( peer  = =  chan )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pu - > notquiteyet  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Wake up the (presumably select()ing) thread */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pthread_kill ( parking_thread ,  SIGURG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_verb ( 2 ,  " Parked %s on %d (lot %s). Will timeout back to extension [%s] %s, %d in %d seconds \n " ,  pu - > chan - > name ,  pu - > parkingnum ,  parkinglot - > name ,  pu - > context ,  pu - > exten ,  pu - > priority ,  ( pu - > parkingtime / 1000 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									manager_event ( EVENT_FLAG_CALL ,  " ParkedCall " , 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" Exten: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" Channel: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" Parkinglot: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" From: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" Timeout: %ld \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2006-10-02 20:35:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" CallerIDNum: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-17 14:12:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" CallerIDName: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" Uniqueid: %s \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pu - > parkingexten ,  pu - > chan - > name ,  pu - > parkinglot - > name ,  peer  ?  peer - > name  :  " " , 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 10:47:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										( long ) pu - > start . tv_sec  +  ( long ) ( pu - > parkingtime / 1000 )  -  ( long ) time ( NULL ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										S_OR ( pu - > chan - > cid . cid_num ,  " <unknown> " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-17 14:12:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										S_OR ( pu - > chan - > cid . cid_name ,  " <unknown> " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pu - > chan - > uniqueid 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-07-02 14:06:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-20 04:34:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( peer  & &  adsipark  & &  ast_adsi_available ( peer ) )  { 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										adsi_announce_park ( peer ,  pu - > parkingexten ) ; 	/* Only supports parking numbers */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-20 04:34:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_adsi_unload_session ( peer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-21 07:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									con  =  ast_context_find_or_create ( NULL ,  NULL ,  parkinglot - > parking_con ,  registrar ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-21 07:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! con ) 	/* Still no context? Bad */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Parking context '%s' does not exist and unable to create \n " ,  parkinglot - > parking_con ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:26:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( con )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ast_add_extension2 ( con ,  1 ,  pu - > parkingexten ,  1 ,  NULL ,  NULL ,  parkedcall ,  ast_strdup ( pu - > parkingexten ) ,  ast_free_ptr ,  registrar ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											notify_metermaids ( pu - > parkingexten ,  parkinglot - > parking_con ,  AST_DEVICE_INUSE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_UNLOCK ( & parkinglot - > parkings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:08:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Only say number if it's a number and the channel hasn't been masqueraded away */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( peer  & &  ! ast_test_flag ( args ,  AST_PARK_OPT_SILENCE )  & &  ( ast_strlen_zero ( args - > orig_chan_name )  | |  ! strcasecmp ( peer - > name ,  args - > orig_chan_name ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-11 15:05:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* If a channel is masqueraded into peer while playing back the parking slot number do not continue playing it back. This is the case if an attended transfer occurs. */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 20:58:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_set_flag ( peer ,  AST_FLAG_MASQ_NOSTREAM ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:08:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Tell the peer channel the number of the parking space */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_say_digits ( peer ,  pu - > parkingnum ,  " " ,  peer - > language ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 20:58:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_clear_flag ( peer ,  AST_FLAG_MASQ_NOSTREAM ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:26:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( peer  = =  chan )  {  /* pu->notquiteyet = 1 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Wake up parking thread if we're really done */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-19 20:44:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_indicate_data ( pu - > chan ,  AST_CONTROL_HOLD ,  
							 
						 
					
						
							
								
									
										
										
										
											2008-05-14 16:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											S_OR ( parkinglot - > mohclass ,  NULL ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											! ast_strlen_zero ( parkinglot - > mohclass )  ?  strlen ( parkinglot - > mohclass )  +  1  :  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pu - > notquiteyet  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pthread_kill ( parking_thread ,  SIGURG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-21 19:20:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief Park a call */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  ast_park_call ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ,  int  timeout ,  int  * extout )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_park_call_args  args  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. timeout  =  timeout , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										. extout  =  extout , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ast_park_call_full ( chan ,  peer ,  & args ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-21 19:20:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:26:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  masq_park_call ( struct  ast_channel  * rchan ,  struct  ast_channel  * peer ,  int  timeout ,  int  * extout ,  int  play_announcement )  
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  * f ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 18:41:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * orig_chan_name  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-12 23:08:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  park_status ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* Make a new, fake channel that we'll use to masquerade in the real one */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-10 05:41:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( chan  =  ast_channel_alloc ( 0 ,  AST_STATE_DOWN ,  0 ,  0 ,  rchan - > accountcode ,  rchan - > exten ,  rchan - > context ,  rchan - > amaflags ,  " Parked/%s " , rchan - > name ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Unable to create parked channel \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-21 07:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Make formats okay */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									chan - > readformat  =  rchan - > readformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									chan - > writeformat  =  rchan - > writeformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_masquerade ( chan ,  rchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Setup the extensions and such */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									set_c_e_p ( chan ,  rchan - > context ,  rchan - > exten ,  rchan - > priority ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Make the masq execute */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-24 20:32:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( f  =  ast_read ( chan ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-21 07:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:26:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! play_announcement )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										orig_chan_name  =  ast_strdupa ( chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 18:41:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_park_call_args  args  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											. timeout  =  timeout , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											. extout  =  extout , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											. orig_chan_name  =  orig_chan_name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-12 23:08:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										park_status  =  ast_park_call_full ( chan ,  peer ,  & args ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( park_status  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* would be nice to play "invalid parking extension" */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 18:41:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:26:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/* Park call via masquraded channel */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  ast_masq_park_call ( struct  ast_channel  * rchan ,  struct  ast_channel  * peer ,  int  timeout ,  int  * extout )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  masq_park_call ( rchan ,  peer ,  timeout ,  extout ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  masq_park_call_announce ( struct  ast_channel  * rchan ,  struct  ast_channel  * peer ,  int  timeout ,  int  * extout )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  masq_park_call ( rchan ,  peer ,  timeout ,  extout ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define FEATURE_SENSE_CHAN	(1 << 0) 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# define FEATURE_SENSE_PEER	(1 << 1) 
  
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  set  caller  and  callee  according  to  the  direction  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  caller ,  callee ,  peer ,  chan ,  sense 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Detect  who  triggered  feature  and  set  callee / caller  variables  accordingly 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:26:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  set_peers ( struct  ast_channel  * * caller ,  struct  ast_channel  * * callee ,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * peer ,  struct  ast_channel  * chan ,  int  sense ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( sense  = =  FEATURE_SENSE_PEER )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* caller  =  peer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* callee  =  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* callee  =  peer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* caller  =  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  support  routing  for  one  touch  call  parking 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  chan  channel  parking  call 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  peer  channel  to  be  parked 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  config  unsed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  code  unused 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  sense  feature  options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-23 20:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  data 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Setup  channel ,  set  return  exten , priority  to  ' s , 1 ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  answer  chan ,  sleep  chan ,  park  call 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2007-08-23 20:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  builtin_parkcall ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ,  struct  ast_bridge_config  * config ,  char  * code ,  int  sense ,  void  * data )  
						 
					
						
							
								
									
										
										
										
											2006-05-22 16:43:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * parker ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-04 23:04:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_channel  * parkee ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 02:11:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-22 16:43:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									set_peers ( & parker ,  & parkee ,  peer ,  chan ,  sense ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Setup the exten/priority to be s/1 since we don't know
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   where  this  call  should  return  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									strcpy ( chan - > exten ,  " s " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									chan - > priority  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( chan - > _state  ! =  AST_STATE_UP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  ast_answer ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  ast_safe_sleep ( chan ,  1000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 02:11:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-22 16:43:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:26:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( sense  = =  FEATURE_SENSE_CHAN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  ast_park_call ( parkee ,  parker ,  0 ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( sense  = =  FEATURE_SENSE_CHAN )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 152535 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r152535 | murf | 2008-10-28 22:36:32 -0600 (Tue, 28 Oct 2008) | 46 lines
The magic trick to avoid this crash is not to
try to find the channel by name in the list,
which is slow and resource consuming, but rather
to pay attention to the result codes from the
ast_bridge_call, to which I added the 
AST_PBX_NO_HANGUP_PEER_PARKED value, which
now are returned when a channel is parked.
Why? because CDR's aren't generated via parking,
so nothing is needed, but if a transfer occurred,
there are critical things I need.
If you get AST_PBX_KEEPALIVE,
then don't touch the channel pointer.
If you get AST_PBX_NO_HANGUP_PEER, or
AST_PBX_NO_HANGUP_PEER_PARKED, then don't
touch the peer pointer.
Updated the several places where the results
from a bridge were not being properly obeyed,
and fixed some code I had introduced so that
the results of the bridge were not overridden 
(in trunk).
All the places that previously tested for 
AST_PBX_NO_HANGUP_PEER now have to check for
both AST_PBX_NO_HANGUP_PEER and AST_PBX_NO_HANGUP_PEER_PARKED.
I tested this against the 4 common parking
scenarios:
1. A calls B; B answers; A parks B; B hangs up while A is getting the parking
slot announcement, immediately after being put on hold.
2. A calls B; B answers; A parks B; B hangs up after A has been hung up, but
before the park times out.
3. A calls B; B answers; B parks A; A hangs up while B is getting the parking slot announcement, immediately after being put on hold.
4. A calls B; B answers; B parks A; A hangs up after B has been hung up, but before the park times out.
No crash.
I also ran the scenarios above against valgrind, and accesses looked good.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@152536 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-10-29 05:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													res  =  AST_PBX_NO_HANGUP_PEER_PARKED ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:26:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  AST_PBX_KEEPALIVE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( sense  = =  FEATURE_SENSE_PEER )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											masq_park_call_announce ( parkee ,  parker ,  0 ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  0 ;  /* PBX should hangup zombie channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-22 16:43:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:26:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-22 16:43:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-12 18:39:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief Play message to both caller and callee in bridged call, plays synchronously, autoservicing the
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									other  channel  during  the  message ,  so  please  don ' t  use  this  for  very  long  messages 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  play_message_in_bridged_call ( struct  ast_channel  * caller_chan ,  struct  ast_channel  * callee_chan ,  const  char  * audiofile )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* First play for caller, put other channel on auto service */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_autoservice_start ( callee_chan ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_stream_and_wait ( caller_chan ,  audiofile ,  " " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Failed to play automon message! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_autoservice_stop ( callee_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_autoservice_stop ( callee_chan ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Then play for callee, put other channel on auto service */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_autoservice_start ( caller_chan ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_stream_and_wait ( callee_chan ,  audiofile ,  " " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Failed to play automon message ! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_autoservice_stop ( caller_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_autoservice_stop ( caller_chan ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Monitor  a  channel  by  DTMF 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  chan  channel  requesting  monitor 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  peer  channel  to  be  monitored 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  config 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  code 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  sense  feature  options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-23 20:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  data 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Check  monitor  app  enabled ,  setup  channels ,  both  caller / callee  chans  not  null 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  get  TOUCH_MONITOR  variable  for  filename  if  exists ,  exec  monitor  app . 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ retval  AST_FEATURE_RETURN_SUCCESS  on  success . 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ retval  - 1  on  error . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2007-08-23 20:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  builtin_automonitor ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ,  struct  ast_bridge_config  * config ,  char  * code ,  int  sense ,  void  * data )  
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2005-12-08 18:18:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * caller_chan_id  =  NULL ,  * callee_chan_id  =  NULL ,  * args  =  NULL ,  * touch_filename  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  x  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  len ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_channel  * caller_chan ,  * callee_chan ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-12 18:39:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * automon_message_start  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * automon_message_stop  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-11 18:24:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! monitor_ok )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR , " Cannot record the call. The monitor application is disabled. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 18:37:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! monitor_app  & &  ! ( monitor_app  =  pbx_findapp ( " Monitor " ) ) )  { 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										monitor_ok  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 18:37:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR , " Cannot record the call. The monitor application is disabled. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:26:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									set_peers ( & caller_chan ,  & callee_chan ,  peer ,  chan ,  sense ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-12 18:39:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( caller_chan )  { 	/* Find extra messages */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										automon_message_start  =  pbx_builtin_getvar_helper ( caller_chan ,  " TOUCH_MONITOR_MESSAGE_START " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										automon_message_stop  =  pbx_builtin_getvar_helper ( caller_chan ,  " TOUCH_MONITOR_MESSAGE_STOP " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:26:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-12 18:39:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ast_strlen_zero ( courtesytone ) )  { 	/* Play courtesy tone if configured */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if ( play_message_in_bridged_call ( caller_chan ,  callee_chan ,  courtesytone )  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 22:46:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 22:38:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-01-11 18:24:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( callee_chan - > monitor )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_verb ( 4 ,  " User hit '%s' to stop recording call. \n " ,  code ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-12 18:39:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ast_strlen_zero ( automon_message_stop ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											play_message_in_bridged_call ( caller_chan ,  callee_chan ,  automon_message_stop ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										callee_chan - > monitor - > stop ( callee_chan ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  AST_FEATURE_RETURN_SUCCESS ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-11 18:24:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( caller_chan  & &  callee_chan )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-03 19:25:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  char  * touch_format  =  pbx_builtin_getvar_helper ( caller_chan ,  " TOUCH_MONITOR_FORMAT " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  char  * touch_monitor  =  pbx_builtin_getvar_helper ( caller_chan ,  " TOUCH_MONITOR " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-15 20:08:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  char  * touch_monitor_prefix  =  pbx_builtin_getvar_helper ( caller_chan ,  " TOUCH_MONITOR_PREFIX " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-03 19:25:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-05-16 00:43:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! touch_format ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											touch_format  =  pbx_builtin_getvar_helper ( callee_chan ,  " TOUCH_MONITOR_FORMAT " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! touch_monitor ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-11 18:24:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											touch_monitor  =  pbx_builtin_getvar_helper ( callee_chan ,  " TOUCH_MONITOR " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-08 18:18:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2007-10-15 20:08:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! touch_monitor_prefix ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											touch_monitor_prefix  =  pbx_builtin_getvar_helper ( callee_chan ,  " TOUCH_MONITOR_PREFIX " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( touch_monitor )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											len  =  strlen ( touch_monitor )  +  50 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											args  =  alloca ( len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-08 18:18:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											touch_filename  =  alloca ( len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-15 20:08:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											snprintf ( touch_filename ,  len ,  " %s-%ld-%s " ,  S_OR ( touch_monitor_prefix ,  " auto " ) ,  ( long ) time ( NULL ) ,  touch_monitor ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-26 14:51:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											snprintf ( args ,  len ,  " %s,%s,m " ,  S_OR ( touch_format ,  " wav " ) ,  touch_filename ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 10:47:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											caller_chan_id  =  ast_strdupa ( S_OR ( caller_chan - > cid . cid_num ,  caller_chan - > name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											callee_chan_id  =  ast_strdupa ( S_OR ( callee_chan - > cid . cid_num ,  callee_chan - > name ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-11 18:24:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											len  =  strlen ( caller_chan_id )  +  strlen ( callee_chan_id )  +  50 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											args  =  alloca ( len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-08 18:18:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											touch_filename  =  alloca ( len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-15 20:08:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											snprintf ( touch_filename ,  len ,  " %s-%ld-%s-%s " ,  S_OR ( touch_monitor_prefix ,  " auto " ) ,  ( long ) time ( NULL ) ,  caller_chan_id ,  callee_chan_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-26 14:51:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											snprintf ( args ,  len ,  " %s,%s,m " ,  S_OR ( touch_format ,  " wav " ) ,  touch_filename ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for ( x  =  0 ;  x  <  strlen ( args ) ;  x + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( args [ x ]  = =  ' / ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												args [ x ]  =  ' - ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 23:20:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_verb ( 4 ,  " User hit '%s' to record call. filename: %s \n " ,  code ,  args ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-30 21:29:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pbx_exec ( callee_chan ,  monitor_app ,  args ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-08 18:18:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( callee_chan ,  " TOUCH_MONITOR_OUTPUT " ,  touch_filename ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( caller_chan ,  " TOUCH_MONITOR_OUTPUT " ,  touch_filename ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-12 18:39:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ast_strlen_zero ( automon_message_start ) )  { 	/* Play start message for both channels */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											play_message_in_bridged_call ( caller_chan ,  callee_chan ,  automon_message_start ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-08 18:18:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  AST_FEATURE_RETURN_SUCCESS ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_log ( LOG_NOTICE , " Cannot record the call. One or both channels have gone away. \n " ) ; 	
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-30 21:19:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  builtin_automixmonitor ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ,  struct  ast_bridge_config  * config ,  char  * code ,  int  sense ,  void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * caller_chan_id  =  NULL ,  * callee_chan_id  =  NULL ,  * args  =  NULL ,  * touch_filename  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  x  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									size_t  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * caller_chan ,  * callee_chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * mixmonitor_spy_type  =  " MixMonitor " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! mixmonitor_ok )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR , " Cannot record the call. The mixmonitor application is disabled. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( mixmonitor_app  =  pbx_findapp ( " MixMonitor " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										mixmonitor_ok  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR , " Cannot record the call. The mixmonitor application is disabled. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									set_peers ( & caller_chan ,  & callee_chan ,  peer ,  chan ,  sense ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ast_strlen_zero ( courtesytone ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_autoservice_start ( callee_chan ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_stream_and_wait ( caller_chan ,  courtesytone ,  " " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Failed to play courtesy tone! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_autoservice_stop ( callee_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_autoservice_stop ( callee_chan ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_lock ( callee_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									count  =  ast_channel_audiohook_count_by_source ( callee_chan ,  mixmonitor_spy_type ,  AST_AUDIOHOOK_TYPE_SPY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unlock ( callee_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* This means a mixmonitor is attached to the channel, running or not is unknown. */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-30 21:19:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( count  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										
							 
						 
					
						
							
								
									
										
										
										
											2007-12-14 14:48:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_verb ( 3 ,  " User hit '%s' to stop recording call. \n " ,  code ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-30 21:19:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Make sure they are running */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-30 21:19:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_channel_lock ( callee_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										count  =  ast_channel_audiohook_count_by_source_running ( callee_chan ,  mixmonitor_spy_type ,  AST_AUDIOHOOK_TYPE_SPY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_unlock ( callee_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( count  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! stopmixmonitor_ok )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_ERROR , " Cannot stop recording the call. The stopmixmonitor application is disabled. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ( stopmixmonitor_app  =  pbx_findapp ( " StopMixMonitor " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												stopmixmonitor_ok  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_ERROR , " Cannot stop recording the call. The stopmixmonitor application is disabled. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												pbx_exec ( callee_chan ,  stopmixmonitor_app ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  AST_FEATURE_RETURN_SUCCESS ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-30 21:19:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING , " Stopped MixMonitors are attached to the channel. \n " ) ; 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 			
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( caller_chan  & &  callee_chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  char  * touch_format  =  pbx_builtin_getvar_helper ( caller_chan ,  " TOUCH_MIXMONITOR_FORMAT " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  char  * touch_monitor  =  pbx_builtin_getvar_helper ( caller_chan ,  " TOUCH_MIXMONITOR " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! touch_format ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											touch_format  =  pbx_builtin_getvar_helper ( callee_chan ,  " TOUCH_MIXMONITOR_FORMAT " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! touch_monitor ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											touch_monitor  =  pbx_builtin_getvar_helper ( callee_chan ,  " TOUCH_MIXMONITOR " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( touch_monitor )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											len  =  strlen ( touch_monitor )  +  50 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											args  =  alloca ( len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											touch_filename  =  alloca ( len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											snprintf ( touch_filename ,  len ,  " auto-%ld-%s " ,  ( long ) time ( NULL ) ,  touch_monitor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											snprintf ( args ,  len ,  " %s.%s,b " ,  touch_filename ,  ( touch_format )  ?  touch_format  :  " wav " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											caller_chan_id  =  ast_strdupa ( S_OR ( caller_chan - > cid . cid_num ,  caller_chan - > name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											callee_chan_id  =  ast_strdupa ( S_OR ( callee_chan - > cid . cid_num ,  callee_chan - > name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											len  =  strlen ( caller_chan_id )  +  strlen ( callee_chan_id )  +  50 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											args  =  alloca ( len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											touch_filename  =  alloca ( len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											snprintf ( touch_filename ,  len ,  " auto-%ld-%s-%s " ,  ( long ) time ( NULL ) ,  caller_chan_id ,  callee_chan_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											snprintf ( args ,  len ,  " %s.%s,b " ,  touch_filename ,  S_OR ( touch_format ,  " wav " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for (  x  =  0 ;  x  <  strlen ( args ) ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( args [ x ]  = =  ' / ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												args [ x ]  =  ' - ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-12-14 14:48:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_verb ( 3 ,  " User hit '%s' to record call. filename: %s \n " ,  code ,  touch_filename ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-30 21:19:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pbx_exec ( callee_chan ,  mixmonitor_app ,  args ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( callee_chan ,  " TOUCH_MIXMONITOR_OUTPUT " ,  touch_filename ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( caller_chan ,  " TOUCH_MIXMONITOR_OUTPUT " ,  touch_filename ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  AST_FEATURE_RETURN_SUCCESS ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-30 21:19:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_log ( LOG_NOTICE , " Cannot record the call. One or both channels have gone away. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-23 20:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  builtin_disconnect ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ,  struct  ast_bridge_config  * config ,  char  * code ,  int  sense ,  void  * data )  
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_verb ( 4 ,  " User hit '%s' to disconnect call. \n " ,  code ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  AST_FEATURE_RETURN_HANGUP ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:26:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  finishup ( struct  ast_channel  * chan )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-03-04 23:04:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_indicate ( chan ,  AST_CONTROL_UNHOLD ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ast_autoservice_stop ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:26:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Find  the  context  for  the  transfer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  transferer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  transferee 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Grab  the  TRANSFER_CONTEXT ,  if  fails  try  grabbing  macrocontext . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  a  context  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:26:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  const  char  * real_ctx ( struct  ast_channel  * transferer ,  struct  ast_channel  * transferee )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-03-04 23:04:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * s  =  pbx_builtin_getvar_helper ( transferer ,  " TRANSFER_CONTEXT " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( s ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  =  pbx_builtin_getvar_helper ( transferee ,  " TRANSFER_CONTEXT " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( s ) )  {  /* Use the non-macro context to transfer the call XXX ? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  =  transferer - > macrocontext ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( s ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										s  =  transferer - > context ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  s ;   
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:26:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Blind  transfer  user  to  another  extension 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  chan  channel  to  be  transfered 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  peer  channel  initiated  blind  transfer 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  config 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  code 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-23 20:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  data 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  sense   feature  options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Place  chan  on  hold ,  check  if  transferred  to  parkinglot  extension , 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  otherwise  check  extension  exists  and  transfer  caller . 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ retval  AST_FEATURE_RETURN_SUCCESS . 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ retval  - 1  on  failure . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2007-08-23 20:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  builtin_blindtransfer ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ,  struct  ast_bridge_config  * config ,  char  * code ,  int  sense ,  void  * data )  
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * transferer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * transferee ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-03 19:25:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * transferer_real_context ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:56:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  xferto [ 256 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:26:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									set_peers ( & transferer ,  & transferee ,  peer ,  chan ,  sense ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									transferer_real_context  =  real_ctx ( transferer ,  transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:41:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Start autoservice on chan while we talk to the originator */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_autoservice_start ( transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-19 20:44:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_indicate ( transferee ,  AST_CONTROL_HOLD ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:56:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									memset ( xferto ,  0 ,  sizeof ( xferto ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-02-17 20:04:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Transfer */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-17 23:18:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  ast_stream_and_wait ( transferer ,  " pbx-transfer " ,  AST_DIGIT_ANY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 21:41:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										finishup ( transferee ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ;  /* error ? */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res  >  0 ) 	/* If they've typed a digit already, handle it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										xferto [ 0 ]  =  ( char )  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-02-17 20:04:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_stopstream ( transferer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:56:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  ast_app_dtget ( transferer ,  transferer_real_context ,  xferto ,  sizeof ( xferto ) ,  100 ,  transferdigittimeout ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 21:41:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res  <  0 )  {   /* hangup, would be 0 for invalid and 1 for valid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										finishup ( transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:56:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! strcmp ( xferto ,  ast_parking_ext ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 21:41:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										res  =  finishup ( transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-17 12:37:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( res ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 21:41:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else  if  ( ! ast_park_call ( transferee ,  transferer ,  0 ,  NULL ) )  { 	/* success */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* We return non-zero, but tell the PBX not to hang the channel when
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   the  thread  dies  - -  We  have  to  be  careful  now  though .   We  are  responsible  for  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											   hanging  up  the  channel ,  else  it  will  never  be  hung  up !  */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-21 15:17:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 152535 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r152535 | murf | 2008-10-28 22:36:32 -0600 (Tue, 28 Oct 2008) | 46 lines
The magic trick to avoid this crash is not to
try to find the channel by name in the list,
which is slow and resource consuming, but rather
to pay attention to the result codes from the
ast_bridge_call, to which I added the 
AST_PBX_NO_HANGUP_PEER_PARKED value, which
now are returned when a channel is parked.
Why? because CDR's aren't generated via parking,
so nothing is needed, but if a transfer occurred,
there are critical things I need.
If you get AST_PBX_KEEPALIVE,
then don't touch the channel pointer.
If you get AST_PBX_NO_HANGUP_PEER, or
AST_PBX_NO_HANGUP_PEER_PARKED, then don't
touch the peer pointer.
Updated the several places where the results
from a bridge were not being properly obeyed,
and fixed some code I had introduced so that
the results of the bridge were not overridden 
(in trunk).
All the places that previously tested for 
AST_PBX_NO_HANGUP_PEER now have to check for
both AST_PBX_NO_HANGUP_PEER and AST_PBX_NO_HANGUP_PEER_PARKED.
I tested this against the 4 common parking
scenarios:
1. A calls B; B answers; A parks B; B hangs up while A is getting the parking
slot announcement, immediately after being put on hold.
2. A calls B; B answers; A parks B; B hangs up after A has been hung up, but
before the park times out.
3. A calls B; B answers; B parks A; A hangs up while B is getting the parking slot announcement, immediately after being put on hold.
4. A calls B; B answers; B parks A; A hangs up after B has been hung up, but before the park times out.
No crash.
I also ran the scenarios above against valgrind, and accesses looked good.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@152536 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-10-29 05:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  ( transferer  = =  peer )  ?  AST_PBX_KEEPALIVE  :  AST_PBX_NO_HANGUP_PEER_PARKED ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Unable to park call %s \n " ,  transferee - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-17 04:31:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/*! \todo XXX Maybe we should have another message here instead of invalid extension XXX */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:56:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( ast_exists_extension ( transferee ,  transferer_real_context ,  xferto ,  1 ,  transferer - > cid . cid_num ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-18 15:38:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( transferer ,  " BLINDTRANSFER " ,  transferee - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( transferee ,  " BLINDTRANSFER " ,  transferer - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 21:41:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										res = finishup ( transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-30 14:37:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! transferer - > cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											transferer - > cdr = ast_cdr_alloc ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-30 17:57:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( transferer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_cdr_init ( transferer - > cdr ,  transferer ) ;  /* initilize our channel's cdr */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_cdr_start ( transferer - > cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( transferer - > cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cdr_setdestchan ( transferer - > cdr ,  transferee - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cdr_setapp ( transferer - > cdr ,  " BLINDTRANSFER " , " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-30 14:37:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-14 15:30:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! transferee - > pbx )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Doh!  Use our handy async_goto functions */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-14 14:48:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_verb ( 3 ,  " Transferring %s to '%s' (context %s) priority 1 \n " 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-14 15:30:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
																, transferee - > name ,  xferto ,  transferer_real_context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_async_goto ( transferee ,  transferer_real_context ,  xferto ,  1 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Async goto failed :-( \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Set the channel's new extension, since it exists, using transferer context */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											set_c_e_p ( transferee ,  transferer_real_context ,  xferto ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-22 02:55:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										check_goto_on_transfer ( transferer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_verb ( 3 ,  " Unable to find extension '%s' in context '%s' \n " ,  xferto ,  transferer_real_context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ast_stream_and_wait ( transferer ,  xferfailsound ,  AST_DIGIT_ANY )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 21:41:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										finishup ( transferee ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_stopstream ( transferer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 21:41:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  finishup ( transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_verb ( 2 ,  " Hungup during autoservice stop on '%s' \n " ,  transferee - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  AST_FEATURE_RETURN_SUCCESS ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  make  channels  compatible 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  c 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  newchan 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  on  success . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  on  failure . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  check_compat ( struct  ast_channel  * c ,  struct  ast_channel  * newchan )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_channel_make_compatible ( c ,  newchan )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Had to drop call because I couldn't make %s compatible with %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											c - > name ,  newchan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_hangup ( newchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Attended  transfer 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  chan  transfered  user 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  peer  person  transfering  call 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  config 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  code 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  sense  feature  options 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  
							 
						 
					
						
							
								
									
										
										
										
											2007-08-23 20:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  data 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Get  extension  to  transfer  to ,  if  you  cannot  generate  channel  ( or  find  extension )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  return  to  host  channel .  After  called  channel  answered  wait  for  hangup  of  transferer , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  bridge  call  between  transfer  peer  ( taking  them  off  hold )  to  attended  transfer  channel . 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  - 1  on  failure 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2007-08-23 20:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  builtin_atxfer ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ,  struct  ast_bridge_config  * config ,  char  * code ,  int  sense ,  void  * data )  
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * transferer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * transferee ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-03 19:25:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * transferer_real_context ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-19 20:44:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  xferto [ 256 ]  =  " " ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  outstate = 0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * newchan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * xferchan ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_bridge_thread_obj  * tobj ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_bridge_config  bconfig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  * f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  l ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 1 ,  " Executing Attended Transfer %s, %s (sense=%d)  \n " ,  chan - > name ,  peer - > name ,  sense ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:26:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									set_peers ( & transferer ,  & transferee ,  peer ,  chan ,  sense ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-04 23:04:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									transferer_real_context  =  real_ctx ( transferer ,  transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:41:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Start autoservice on chan while we talk to the originator */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_autoservice_start ( transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-19 20:44:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_indicate ( transferee ,  AST_CONTROL_HOLD ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Transfer */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-17 23:18:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  ast_stream_and_wait ( transferer ,  " pbx-transfer " ,  AST_DIGIT_ANY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 22:22:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										finishup ( transferee ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  >  0 )  /* If they've typed a digit already, handle it */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 22:22:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										xferto [ 0 ]  =  ( char )  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:26:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 22:22:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* this is specific of atxfer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  ast_app_dtget ( transferer ,  transferer_real_context ,  xferto ,  sizeof ( xferto ) ,  100 ,  transferdigittimeout ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-04 23:04:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res  <  0 )  {   /* hangup, would be 0 for invalid and 1 for valid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										finishup ( transferee ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 23:05:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 22:22:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Did not read data. \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 23:05:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										finishup ( transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-17 23:18:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_stream_and_wait ( transferer ,  " beeperr " ,  " " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 22:22:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  AST_FEATURE_RETURN_SUCCESS ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 23:05:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 23:05:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* valid extension, res == 1 */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ast_exists_extension ( transferer ,  transferer_real_context ,  xferto ,  1 ,  transferer - > cid . cid_num ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Extension %s does not exist in context %s \n " , xferto , transferer_real_context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										finishup ( transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-17 23:18:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_stream_and_wait ( transferer ,  " beeperr " ,  " " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  AST_FEATURE_RETURN_SUCCESS ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									l  =  strlen ( xferto ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									snprintf ( xferto  +  l ,  sizeof ( xferto )  -  l ,  " @%s/n " ,  transferer_real_context ) ; 	/* append context */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-30 16:40:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* If we are performing an attended transfer and we have two channels involved then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   copy  sound  file  information  to  play  upon  attended  transfer  completion  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( transferee )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  char  * chan1_attended_sound  =  pbx_builtin_getvar_helper ( transferer ,  " ATTENDED_TRANSFER_COMPLETE_SOUND " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										const  char  * chan2_attended_sound  =  pbx_builtin_getvar_helper ( transferee ,  " ATTENDED_TRANSFER_COMPLETE_SOUND " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ast_strlen_zero ( chan1_attended_sound ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pbx_builtin_setvar_helper ( transferer ,  " BRIDGE_PLAY_SOUND " ,  chan1_attended_sound ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ast_strlen_zero ( chan2_attended_sound ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											pbx_builtin_setvar_helper ( transferee ,  " BRIDGE_PLAY_SOUND " ,  chan2_attended_sound ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									newchan  =  ast_feature_request_and_dial ( transferer ,  transferee ,  " Local " ,  ast_best_codec ( transferer - > nativeformats ) , 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-27 17:31:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										xferto ,  atxfernoanswertimeout ,  & outstate ,  transferer - > cid . cid_num ,  transferer - > cid . cid_name ,  1 ,  transferer - > language ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ast_check_hangup ( transferer ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Transferer is up - old behaviour */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_indicate ( transferer ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! newchan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											finishup ( transferee ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* any reason besides user requested cancel and busy triggers the failed sound */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( outstate  ! =  AST_CONTROL_UNHOLD  & &  outstate  ! =  AST_CONTROL_BUSY  & & 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-17 23:18:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_stream_and_wait ( transferer ,  xferfailsound ,  " " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_stream_and_wait ( transferer ,  xfersound ,  " " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Failed to play transfer sound! \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  AST_FEATURE_RETURN_SUCCESS ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-02 18:59:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( check_compat ( transferer ,  newchan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* we do mean transferee here, NOT transferer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											finishup ( transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-02 18:59:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										memset ( & bconfig , 0 , sizeof ( struct  ast_bridge_config ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_set_flag ( & ( bconfig . features_caller ) ,  AST_FEATURE_DISCONNECT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_set_flag ( & ( bconfig . features_callee ) ,  AST_FEATURE_DISCONNECT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  ast_bridge_call ( transferer ,  newchan ,  & bconfig ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-01 15:39:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_check_hangup ( newchan )  | |  ! ast_check_hangup ( transferer ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_hangup ( newchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_stream_and_wait ( transferer ,  xfersound ,  " " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Failed to play transfer sound! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											finishup ( transferee ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											transferer - > _softhangup  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  AST_FEATURE_RETURN_SUCCESS ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-02 18:59:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( check_compat ( transferee ,  newchan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											finishup ( transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-02 18:59:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_indicate ( transferee ,  AST_CONTROL_UNHOLD ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( ast_autoservice_stop ( transferee )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 | |  ( ast_waitfordigit ( transferee ,  100 )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 | |  ( ast_waitfordigit ( newchan ,  100 )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 | |  ast_check_hangup ( transferee ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 | |  ast_check_hangup ( newchan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( newchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										xferchan  =  ast_channel_alloc ( 0 ,  AST_STATE_DOWN ,  0 ,  0 ,  " " ,  " " ,  " " ,  0 ,  " Transfered/%s " ,  transferee - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! xferchan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( newchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Make formats okay */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-11 19:23:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										xferchan - > visible_indication  =  transferer - > visible_indication ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										xferchan - > readformat  =  transferee - > readformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										xferchan - > writeformat  =  transferee - > writeformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_masquerade ( xferchan ,  transferee ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_explicit_goto ( xferchan ,  transferee - > context ,  transferee - > exten ,  transferee - > priority ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										xferchan - > _state  =  AST_STATE_UP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_clear_flag ( xferchan ,  AST_FLAGS_ALL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										xferchan - > _softhangup  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( f  =  ast_read ( xferchan ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newchan - > _state  =  AST_STATE_UP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_clear_flag ( newchan ,  AST_FLAGS_ALL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newchan - > _softhangup  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( tobj  =  ast_calloc ( 1 ,  sizeof ( * tobj ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( xferchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( newchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-18 16:58:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tobj - > chan  =  newchan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tobj - > peer  =  xferchan ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tobj - > bconfig  =  * config ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-18 18:31:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( tobj - > bconfig . end_bridge_callback_data_fixup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tobj - > bconfig . end_bridge_callback_data_fixup ( & tobj - > bconfig ,  tobj - > peer ,  tobj - > chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_stream_and_wait ( newchan ,  xfersound ,  " " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-08 11:22:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Failed to play transfer sound! \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_bridge_call_thread_launch ( tobj ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ;       /* XXX meaning the channel is bridged ? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( ! ast_check_hangup ( transferee ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* act as blind transfer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_autoservice_stop ( transferee )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( newchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! newchan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											unsigned  int  tries  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-06 20:32:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											char  * transferer_tech ,  * transferer_name  =  ast_strdupa ( transferer - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-06 20:32:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											transferer_tech  =  strsep ( & transferer_name ,  " / " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											transferer_name  =  strsep ( & transferer_name ,  " - " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_strlen_zero ( transferer_name )  | |  ast_strlen_zero ( transferer_tech ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Transferer has invalid channel name: '%s' \n " ,  transferer - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ast_stream_and_wait ( transferee ,  " beeperr " ,  " " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  AST_FEATURE_RETURN_SUCCESS ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-06 20:32:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_log ( LOG_NOTICE ,  " We're trying to call %s/%s \n " ,  transferer_tech ,  transferer_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											newchan  =  ast_feature_request_and_dial ( transferee ,  NULL ,  transferer_tech ,  ast_best_codec ( transferee - > nativeformats ) , 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-27 17:31:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												transferer_name ,  atxfernoanswertimeout ,  & outstate ,  transferee - > cid . cid_num ,  transferee - > cid . cid_name ,  0 ,  transferer - > language ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											while  ( ! newchan  & &  ! atxferdropcall  & &  tries  <  atxfercallbackretries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Trying to transfer again */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_autoservice_start ( transferee ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_indicate ( transferee ,  AST_CONTROL_HOLD ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												newchan  =  ast_feature_request_and_dial ( transferer ,  transferee ,  " Local " ,  ast_best_codec ( transferer - > nativeformats ) , 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-27 17:31:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													xferto ,  atxfernoanswertimeout ,  & outstate ,  transferer - > cid . cid_num ,  transferer - > cid . cid_name ,  1 ,  transferer - > language ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ast_autoservice_stop ( transferee )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-17 02:20:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( newchan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_hangup ( newchan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! newchan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Transfer failed, sleeping */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Sleeping for %d ms before callback. \n " ,  atxferloopdelay ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_safe_sleep ( transferee ,  atxferloopdelay ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Trying to callback... \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-06 20:32:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													newchan  =  ast_feature_request_and_dial ( transferee ,  NULL ,  transferer_tech ,  ast_best_codec ( transferee - > nativeformats ) , 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-27 17:31:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														transferer_name ,  atxfernoanswertimeout ,  & outstate ,  transferee - > cid . cid_num ,  transferee - > cid . cid_name ,  0 ,  transferer - > language ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												tries + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! newchan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* newchan is up, we should prepare transferee and bridge them */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-02 18:59:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( check_compat ( transferee ,  newchan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											finishup ( transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-02 18:59:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_indicate ( transferee ,  AST_CONTROL_UNHOLD ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( ast_waitfordigit ( transferee ,  100 )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   | |  ( ast_waitfordigit ( newchan ,  100 )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   | |  ast_check_hangup ( transferee ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   | |  ast_check_hangup ( newchan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( newchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										xferchan  =  ast_channel_alloc ( 0 ,  AST_STATE_DOWN ,  0 ,  0 ,  " " ,  " " ,  " " ,  0 ,  " Transfered/%s " ,  transferee - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! xferchan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( newchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Make formats okay */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-11 19:23:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										xferchan - > visible_indication  =  transferer - > visible_indication ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										xferchan - > readformat  =  transferee - > readformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										xferchan - > writeformat  =  transferee - > writeformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_masquerade ( xferchan ,  transferee ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_explicit_goto ( xferchan ,  transferee - > context ,  transferee - > exten ,  transferee - > priority ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										xferchan - > _state  =  AST_STATE_UP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_clear_flag ( xferchan ,  AST_FLAGS_ALL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										xferchan - > _softhangup  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( f  =  ast_read ( xferchan ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newchan - > _state  =  AST_STATE_UP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_clear_flag ( newchan ,  AST_FLAGS_ALL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										newchan - > _softhangup  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( tobj  =  ast_calloc ( 1 ,  sizeof ( * tobj ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( xferchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( newchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-18 16:58:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tobj - > chan  =  newchan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tobj - > peer  =  xferchan ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										tobj - > bconfig  =  * config ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-18 18:31:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( tobj - > bconfig . end_bridge_callback_data_fixup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											tobj - > bconfig . end_bridge_callback_data_fixup ( & tobj - > bconfig ,  tobj - > peer ,  tobj - > chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_stream_and_wait ( newchan ,  xfersound ,  " " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Failed to play transfer sound! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_bridge_call_thread_launch ( tobj ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ;       /* XXX meaning the channel is bridged ? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Transferee hung up */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										finishup ( transferee ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 13:05:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-05 19:56:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/* add atxfer and automon as undefined so you can only use em if you configure them */  
						 
					
						
							
								
									
										
										
										
											2007-05-01 22:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define FEATURES_COUNT ARRAY_LEN(builtin_features) 
  
						 
					
						
							
								
									
										
										
										
											2006-01-19 22:09:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								AST_RWLOCK_DEFINE_STATIC ( features_lock ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_call_feature  builtin_features [ ]  =   
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-08-29 21:20:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{  AST_FEATURE_REDIRECT ,  " Blind Transfer " ,  " blindxfer " ,  " # " ,  " # " ,  builtin_blindtransfer ,  AST_FEATURE_FLAG_NEEDSDTMF ,  " "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  AST_FEATURE_REDIRECT ,  " Attended Transfer " ,  " atxfer " ,  " " ,  " " ,  builtin_atxfer ,  AST_FEATURE_FLAG_NEEDSDTMF ,  " "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  AST_FEATURE_AUTOMON ,  " One Touch Monitor " ,  " automon " ,  " " ,  " " ,  builtin_automonitor ,  AST_FEATURE_FLAG_NEEDSDTMF ,  " "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  AST_FEATURE_DISCONNECT ,  " Disconnect Call " ,  " disconnect " ,  " * " ,  " * " ,  builtin_disconnect ,  AST_FEATURE_FLAG_NEEDSDTMF ,  " "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									{  AST_FEATURE_PARKCALL ,  " Park Call " ,  " parkcall " ,  " " ,  " " ,  builtin_parkcall ,  AST_FEATURE_FLAG_NEEDSDTMF ,  " "  } , 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-30 21:19:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									{  AST_FEATURE_AUTOMIXMON ,  " One Touch MixMonitor " ,  " automixmon " ,  " " ,  " " ,  builtin_automixmonitor ,  AST_FEATURE_FLAG_NEEDSDTMF ,  " "  } , 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  AST_RWLIST_HEAD_STATIC ( feature_list ,  ast_call_feature ) ;  
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-19 22:09:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief register new feature into feature_list*/  
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ast_register_feature ( struct  ast_call_feature  * feature )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! feature )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_NOTICE , " You didn't pass a feature! \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 18:43:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								  
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_RWLIST_WRLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_INSERT_HEAD ( & feature_list , feature , feature_entry ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_verb ( 2 ,  " Registered Feature '%s' \n " , feature - > sname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Add  new  feature  group 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  fgname  feature  group  name . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Add  new  feature  group  to  the  feature  group  list  insert  at  head  of  list . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note  This  function  MUST  be  called  while  feature_groups  is  locked . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  feature_group *  register_group ( const  char  * fgname )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  feature_group  * fg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! fgname )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_NOTICE ,  " You didn't pass a new group name! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( fg  =  ast_calloc ( 1 ,  sizeof ( * fg ) ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_string_field_init ( fg ,  128 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_free ( fg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_string_field_set ( fg ,  gname ,  fgname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_INSERT_HEAD ( & feature_groups ,  fg ,  entry ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_verb ( 2 ,  " Registered group '%s' \n " ,  fg - > gname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  fg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Add  feature  to  group 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  fg  feature  group 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  exten 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  feature  feature  to  add . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Check  fg  and  feature  specified ,  add  feature  to  list 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ note  This  function  MUST  be  called  while  feature_groups  is  locked .  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  register_group_feature ( struct  feature_group  * fg ,  const  char  * exten ,  struct  ast_call_feature  * feature )   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  feature_group_exten  * fge ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! fg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_NOTICE ,  " You didn't pass a group! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! feature )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_NOTICE ,  " You didn't pass a feature! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-17 18:14:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( fge  =  ast_calloc ( 1 ,  sizeof ( * fge ) ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_string_field_init ( fge ,  128 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_free ( fge ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_string_field_set ( fge ,  exten ,  S_OR ( exten ,  feature - > exten ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fge - > feature  =  feature ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_INSERT_HEAD ( & fg - > features ,  fge ,  entry ) ; 		
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_verb ( 2 ,  " Registered feature '%s' for group '%s' at exten '%s' \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													feature - > sname ,  fg - > gname ,  exten ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ast_unregister_feature ( struct  ast_call_feature  * feature )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! feature )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 18:37:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_WRLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_REMOVE ( & feature_list ,  feature ,  feature_entry ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_free ( feature ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief Remove all features in the list */  
						 
					
						
							
								
									
										
										
										
											2005-08-23 14:40:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  ast_unregister_features ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_call_feature  * feature ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_RWLIST_WRLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( feature  =  AST_RWLIST_REMOVE_HEAD ( & feature_list ,  feature_entry ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_free ( feature ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 14:40:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-04 17:49:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief find a call feature by name */  
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:54:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_call_feature  * find_dynamic_feature ( const  char  * name )  
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_call_feature  * tmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_RWLIST_TRAVERSE ( & feature_list ,  tmp ,  feature_entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( tmp - > sname ,  name ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 21:36:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  tmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief Remove all feature groups in the list */  
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  ast_unregister_groups ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  feature_group  * fg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  feature_group_exten  * fge ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_WRLOCK ( & feature_groups ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( fg  =  AST_LIST_REMOVE_HEAD ( & feature_groups ,  entry ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( ( fge  =  AST_LIST_REMOVE_HEAD ( & fg - > features ,  entry ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-04 19:44:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_string_field_free_memory ( fge ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_free ( fge ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-04 19:44:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_string_field_free_memory ( fg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_free ( fg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & feature_groups ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Find  a  group  by  name  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  name  feature  name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  feature  group  on  success . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  NULL  on  failure . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  feature_group  * find_group ( const  char  * name )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  feature_group  * fg  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_TRAVERSE ( & feature_groups ,  fg ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( fg - > gname ,  name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  fg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:41:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								void  ast_rdlock_call_features ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rwlock_rdlock ( & features_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								void  ast_unlock_call_features ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rwlock_unlock ( & features_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  ast_call_feature  * ast_find_call_feature ( const  char  * name )  
						 
					
						
							
								
									
										
										
										
											2007-05-04 18:47:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( x  =  0 ;  x  <  FEATURES_COUNT ;  x + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:41:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( name ,  builtin_features [ x ] . sname ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-04 18:47:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  & builtin_features [ x ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  exec  an  app  by  feature  
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  chan , peer , config , code , sense , data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Find  a  feature ,  determine  which  channel  activated 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ retval  AST_FEATURE_RETURN_PBX_KEEPALIVE , AST_FEATURE_RETURN_NO_HANGUP_PEER 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ retval  - 1  error . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 2  when  an  application  cannot  be  found . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2007-08-23 20:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  feature_exec_app ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ,  struct  ast_bridge_config  * config ,  char  * code ,  int  sense ,  void  * data )  
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_app  * app ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-23 20:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_call_feature  * feature  =  data ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 21:20:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_channel  * work ,  * idle ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! feature )  {  /* shouldn't ever happen! */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_NOTICE ,  " Found feature before, but at execing we've lost it?? \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ;  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-07 04:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( sense  = =  FEATURE_SENSE_CHAN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ast_test_flag ( feature ,  AST_FEATURE_FLAG_BYCALLER ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  AST_FEATURE_RETURN_KEEPTRYING ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 21:20:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_test_flag ( feature ,  AST_FEATURE_FLAG_ONSELF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											work  =  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											idle  =  peer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											work  =  peer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											idle  =  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-07 04:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ast_test_flag ( feature ,  AST_FEATURE_FLAG_BYCALLEE ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  AST_FEATURE_RETURN_KEEPTRYING ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 21:20:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_test_flag ( feature ,  AST_FEATURE_FLAG_ONSELF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											work  =  peer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											idle  =  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											work  =  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											idle  =  peer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-07 04:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( app  =  pbx_findapp ( feature - > app ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Could not find application (%s) \n " ,  feature - > app ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-05 23:08:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  - 2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-07 04:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 21:20:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_autoservice_start ( idle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ast_strlen_zero ( feature - > moh_class ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_moh_start ( idle ,  feature - > moh_class ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-07 04:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  pbx_exec ( work ,  app ,  feature - > app_args ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 21:20:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ast_strlen_zero ( feature - > moh_class ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_moh_stop ( idle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_autoservice_stop ( idle ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-09-04 17:27:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res  = =  AST_PBX_KEEPALIVE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* do not hangup peer if feature is to be activated on it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( ast_test_flag ( feature ,  AST_FEATURE_FLAG_ONPEER )  & &  sense  = =  FEATURE_SENSE_CHAN )  | |  ( ast_test_flag ( feature ,  AST_FEATURE_FLAG_ONSELF )  & &  sense  = =  FEATURE_SENSE_PEER ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  AST_FEATURE_RETURN_NO_HANGUP_PEER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  AST_FEATURE_RETURN_PBX_KEEPALIVE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-07 04:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  if  ( res  = =  AST_PBX_NO_HANGUP_PEER ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  AST_FEATURE_RETURN_NO_HANGUP_PEER ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 152535 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r152535 | murf | 2008-10-28 22:36:32 -0600 (Tue, 28 Oct 2008) | 46 lines
The magic trick to avoid this crash is not to
try to find the channel by name in the list,
which is slow and resource consuming, but rather
to pay attention to the result codes from the
ast_bridge_call, to which I added the 
AST_PBX_NO_HANGUP_PEER_PARKED value, which
now are returned when a channel is parked.
Why? because CDR's aren't generated via parking,
so nothing is needed, but if a transfer occurred,
there are critical things I need.
If you get AST_PBX_KEEPALIVE,
then don't touch the channel pointer.
If you get AST_PBX_NO_HANGUP_PEER, or
AST_PBX_NO_HANGUP_PEER_PARKED, then don't
touch the peer pointer.
Updated the several places where the results
from a bridge were not being properly obeyed,
and fixed some code I had introduced so that
the results of the bridge were not overridden 
(in trunk).
All the places that previously tested for 
AST_PBX_NO_HANGUP_PEER now have to check for
both AST_PBX_NO_HANGUP_PEER and AST_PBX_NO_HANGUP_PEER_PARKED.
I tested this against the 4 common parking
scenarios:
1. A calls B; B answers; A parks B; B hangs up while A is getting the parking
slot announcement, immediately after being put on hold.
2. A calls B; B answers; A parks B; B hangs up after A has been hung up, but
before the park times out.
3. A calls B; B answers; B parks A; A hangs up while B is getting the parking slot announcement, immediately after being put on hold.
4. A calls B; B answers; B parks A; A hangs up after B has been hung up, but before the park times out.
No crash.
I also ran the scenarios above against valgrind, and accesses looked good.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@152536 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-10-29 05:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  if  ( res  = =  AST_PBX_NO_HANGUP_PEER_PARKED ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  AST_FEATURE_RETURN_NO_HANGUP_PEER_PARKED ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-07 04:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									else  if  ( res ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  AST_FEATURE_RETURN_SUCCESSBREAK ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  AST_FEATURE_RETURN_SUCCESS ; 	/*! \todo XXX should probably return res */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  unmap_features ( void )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rwlock_wrlock ( & features_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( x  =  0 ;  x  <  FEATURES_COUNT ;  x + + ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										strcpy ( builtin_features [ x ] . exten ,  builtin_features [ x ] . default_exten ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_rwlock_unlock ( & features_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  remap_feature ( const  char  * name ,  const  char  * value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:54:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  x ,  res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rwlock_wrlock ( & features_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:54:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( x  =  0 ;  x  <  FEATURES_COUNT ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( strcasecmp ( builtin_features [ x ] . sname ,  name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( builtin_features [ x ] . exten ,  value ,  sizeof ( builtin_features [ x ] . exten ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:54:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_rwlock_unlock ( & features_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Check  the  dynamic  features 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  chan , peer , config , code , sense 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Lock  features  list ,  browse  for  code ,  unlock  list 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  res  on  success . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  on  failure . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  ast_feature_interpret ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ,  struct  ast_bridge_config  * config ,  char  * code ,  int  sense )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 14:46:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_flags  features ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_call_feature  * feature ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  feature_group  * fg  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  feature_group_exten  * fge ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-12 19:50:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * dynamic_features ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * tmp ,  * tok ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-04 17:27:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  res  =  AST_FEATURE_RETURN_PASSDIGITS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  feature_detected  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-12-12 17:51:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( sense  = =  FEATURE_SENSE_CHAN )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_copy_flags ( & features ,  & ( config - > features_caller ) ,  AST_FLAGS_ALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-12 17:51:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dynamic_features  =  pbx_builtin_getvar_helper ( chan ,  " DYNAMIC_FEATURES " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_copy_flags ( & features ,  & ( config - > features_callee ) ,  AST_FLAGS_ALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-12 17:51:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										dynamic_features  =  pbx_builtin_getvar_helper ( peer ,  " DYNAMIC_FEATURES " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-07 20:02:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_debug ( 3 ,  " Feature interpret: chan=%s, peer=%s, code=%s, sense=%d, features=%d, dynamic=%s \n " ,  chan - > name ,  peer - > name ,  code ,  sense ,  features . flags ,  dynamic_features ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 21:36:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_rwlock_rdlock ( & features_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( x  =  0 ;  x  <  FEATURES_COUNT ;  x + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 14:46:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( ast_test_flag ( & features ,  builtin_features [ x ] . feature_mask ) )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										    ! ast_strlen_zero ( builtin_features [ x ] . exten ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Feature is up for consideration */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! strcmp ( builtin_features [ x ] . exten ,  code ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-23 20:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												res  =  builtin_features [ x ] . operation ( chan ,  peer ,  config ,  code ,  sense ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-04 17:27:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												feature_detected  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( ! strncmp ( builtin_features [ x ] . exten ,  code ,  strlen ( code ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( res  = =  AST_FEATURE_RETURN_PASSDIGITS ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  AST_FEATURE_RETURN_STOREDIGITS ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_rwlock_unlock ( & features_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-09-04 17:27:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( dynamic_features )  | |  feature_detected ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tmp  =  ast_strdupa ( dynamic_features ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 21:36:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( ( tok  =  strsep ( & tmp ,  " # " ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										AST_RWLIST_RDLOCK ( & feature_groups ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fg  =  find_group ( tok ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-09-17 16:58:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( fg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											AST_LIST_TRAVERSE ( & fg - > features ,  fge ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( strcasecmp ( fge - > exten ,  code ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  fge - > feature - > operation ( chan ,  peer ,  config ,  code ,  sense ,  fge - > feature ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( res  ! =  AST_FEATURE_RETURN_KEEPTRYING )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-17 16:58:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													AST_RWLIST_UNLOCK ( & feature_groups ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												res  =  AST_FEATURE_RETURN_PASSDIGITS ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-17 16:58:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( fge ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_RWLIST_UNLOCK ( & feature_groups ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										AST_RWLIST_RDLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( feature  =  find_dynamic_feature ( tok ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											AST_RWLIST_UNLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Feature is up for consideration */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcmp ( feature - > exten ,  code ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_verb ( 3 ,  "  Feature Found: %s exten: %s \n " , feature - > sname ,  tok ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-23 20:20:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  feature - > operation ( chan ,  peer ,  config ,  code ,  sense ,  feature ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( res  ! =  AST_FEATURE_RETURN_KEEPTRYING )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												AST_RWLIST_UNLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-17 16:58:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  AST_FEATURE_RETURN_PASSDIGITS ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strncmp ( feature - > exten ,  code ,  strlen ( code ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  AST_FEATURE_RETURN_STOREDIGITS ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										AST_RWLIST_UNLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 21:36:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  set_config_flags ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ,  struct  ast_bridge_config  * config )  
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 21:36:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_clear_flag ( config ,  AST_FLAGS_ALL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rwlock_rdlock ( & features_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 15:33:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( x  =  0 ;  x  <  FEATURES_COUNT ;  x + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ast_test_flag ( builtin_features  +  x ,  AST_FEATURE_FLAG_NEEDSDTMF ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 21:36:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_test_flag ( & ( config - > features_caller ) ,  builtin_features [ x ] . feature_mask ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_set_flag ( config ,  AST_BRIDGE_DTMF_CHANNEL_0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_test_flag ( & ( config - > features_callee ) ,  builtin_features [ x ] . feature_mask ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_set_flag ( config ,  AST_BRIDGE_DTMF_CHANNEL_1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_rwlock_unlock ( & features_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 21:36:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( chan  & &  peer  & &  ! ( ast_test_flag ( config ,  AST_BRIDGE_DTMF_CHANNEL_0 )  & &  ast_test_flag ( config ,  AST_BRIDGE_DTMF_CHANNEL_1 ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-03 19:25:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  char  * dynamic_features  =  pbx_builtin_getvar_helper ( chan ,  " DYNAMIC_FEATURES " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 21:36:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( dynamic_features )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											char  * tmp  =  ast_strdupa ( dynamic_features ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											char  * tok ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  ast_call_feature  * feature ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* while we have a feature */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-10 13:22:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											while  ( ( tok  =  strsep ( & tmp ,  " # " ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												AST_RWLIST_RDLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-08 16:54:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ( feature  =  find_dynamic_feature ( tok ) )  & &  ast_test_flag ( feature ,  AST_FEATURE_FLAG_NEEDSDTMF ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-07 04:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ast_test_flag ( feature ,  AST_FEATURE_FLAG_BYCALLER ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 18:37:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_set_flag ( config ,  AST_BRIDGE_DTMF_CHANNEL_0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-07 04:15:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ast_test_flag ( feature ,  AST_FEATURE_FLAG_BYCALLEE ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 18:37:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_set_flag ( config ,  AST_BRIDGE_DTMF_CHANNEL_1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 21:36:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												AST_RWLIST_UNLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 21:36:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! 
  
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ brief  Get  feature  and  dial 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  caller , transferee , type , format , data , timeout , outstate , cid_num , cid_name , igncallerstate 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Request  channel ,  set  channel  variables ,  initiate  call , check  if  they  want  to  disconnect 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  go  into  loop ,  check  if  timeout  has  elapsed ,  check  if  person  to  be  transfered  hung  up , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  check  for  answer  break  loop ,  set  cdr  return  channel . 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ todo  XXX  Check  -  this  is  very  similar  to  the  code  in  channel . c  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  always  a  channel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2008-02-27 17:31:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_channel  * ast_feature_request_and_dial ( struct  ast_channel  * caller ,  struct  ast_channel  * transferee ,  const  char  * type ,  int  format ,  void  * data ,  int  timeout ,  int  * outstate ,  const  char  * cid_num ,  const  char  * cid_name ,  int  igncallerstate ,  const  char  * language )  
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  state  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  cause  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  to ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * monitor_chans [ 2 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * active_channel ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ,  ready  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  timeval  started ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  x ,  len  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * disconnect_code  =  NULL ,  * dialed_code  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-27 17:31:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( chan  =  ast_request ( type ,  format ,  data ,  & cause ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_NOTICE ,  " Unable to request channel %s/%s \n " ,  type ,  ( char  * ) data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										switch ( cause )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AST_CAUSE_BUSY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											state  =  AST_CONTROL_BUSY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  AST_CAUSE_CONGESTION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											state  =  AST_CONTROL_CONGESTION ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										goto  done ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_set_callerid ( chan ,  cid_num ,  cid_name ,  cid_num ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_string_field_set ( chan ,  language ,  language ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_inherit_variables ( caller ,  chan ) ; 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " TRANSFERERNAME " ,  caller - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_call ( chan ,  data ,  timeout ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_NOTICE ,  " Unable to call channel %s/%s \n " ,  type ,  ( char  * ) data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 20:21:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										goto  done ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_indicate ( caller ,  AST_CONTROL_RINGING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* support dialing of the featuremap disconnect code while performing an attended tranfer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rwlock_rdlock ( & features_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( x  =  0 ;  x  <  FEATURES_COUNT ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( strcasecmp ( builtin_features [ x ] . sname ,  " disconnect " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-28 14:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										disconnect_code  =  builtin_features [ x ] . exten ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										len  =  strlen ( disconnect_code )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										dialed_code  =  alloca ( len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										memset ( dialed_code ,  0 ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_rwlock_unlock ( & features_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									x  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									started  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									to  =  timeout ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-28 14:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_poll_channel_add ( caller ,  chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 20:09:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									while  ( ! ( ( transferee  & &  ast_check_hangup ( transferee ) )  & &  ( ! igncallerstate  & &  ast_check_hangup ( caller ) ) )  & &  timeout  & &  ( chan - > _state  ! =  AST_STATE_UP ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_frame  * f  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										monitor_chans [ 0 ]  =  caller ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										monitor_chans [ 1 ]  =  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										active_channel  =  ast_waitfor_n ( monitor_chans ,  2 ,  & to ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* see if the timeout has been violated */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if ( ast_tvdiff_ms ( ast_tvnow ( ) ,  started )  >  timeout )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											state  =  AST_CONTROL_UNHOLD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_NOTICE ,  " We exceeded our AT-timeout \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ;  /*doh! timeout*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! active_channel ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( chan  & &  ( chan  = =  active_channel ) ) { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f  =  ast_read ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( f  = =  NULL )  {  /*doh! where'd he go?*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												state  =  AST_CONTROL_HANGUP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( f - > frametype  = =  AST_FRAME_CONTROL  | |  f - > frametype  = =  AST_FRAME_DTMF  | |  f - > frametype  = =  AST_FRAME_TEXT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( f - > subclass  = =  AST_CONTROL_RINGING )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													state  =  f - > subclass ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_verb ( 3 ,  " %s is ringing \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_indicate ( caller ,  AST_CONTROL_RINGING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( ( f - > subclass  = =  AST_CONTROL_BUSY )  | |  ( f - > subclass  = =  AST_CONTROL_CONGESTION ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													state  =  f - > subclass ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_verb ( 3 ,  " %s is busy \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_indicate ( caller ,  AST_CONTROL_BUSY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													f  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( f - > subclass  = =  AST_CONTROL_ANSWER )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* This is what we are hoping for */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													state  =  f - > subclass ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													f  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ready = 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  if  ( f - > subclass  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_NOTICE ,  " Don't know what to do about control frame: %d \n " ,  f - > subclass ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* else who cares */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( caller  & &  ( active_channel  = =  caller ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f  =  ast_read ( caller ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( f  = =  NULL )  {  /*doh! where'd he go?*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! igncallerstate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( ast_check_hangup ( caller )  & &  ! ast_check_hangup ( chan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/* make this a blind transfer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ready  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													state  =  AST_CONTROL_HANGUP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( f - > frametype  = =  AST_FRAME_DTMF )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													dialed_code [ x + + ]  =  f - > subclass ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													dialed_code [ x ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( strlen ( dialed_code )  = =  len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														x  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else  if  ( x  & &  strncmp ( dialed_code ,  disconnect_code ,  x ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														x  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														dialed_code [ x ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( * dialed_code  & &  ! strcmp ( dialed_code ,  disconnect_code ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/* Caller Canceled the call */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														state  =  AST_CONTROL_UNHOLD ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														f  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														break ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  /* end while */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_poll_channel_del ( caller ,  chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								done :  
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_indicate ( caller ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( chan  & &  ready )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( chan - > _state  = =  AST_STATE_UP )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											state  =  AST_CONTROL_ANSWER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 19:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  if  ( chan )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 22:12:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										chan  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( outstate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										* outstate  =  state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												Merged revisions 142575 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142575 | murf | 2008-09-11 16:55:49 -0600 (Thu, 11 Sep 2008) | 20 lines
(closes issue #13364)
Reported by: mdu113
Well, fundamentally, the problems revealed in 13364 are
because of the ForkCDR call that is done before the dial. 
When the bridge is in place, it's dealing with the first
(and wrong) cdr in the list.
So, I wrote a little func to zip down to the first non-locked
cdr in the chain, and thru-out the ast_bridge_call, these
results are used instead of raw chan->cdr and peer->cdr pointers.
This shouldn't affect anyone who isn't forking cdrs before a
dial, and should correct the cdr's of those that do.
So, this change ends up correcting the dstchannel
and userfield; the disposition was fixed by a previous
patch, it was OK coming into this problem.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-11 23:12:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  return  the  first  unlocked  cdr  in  a  possible  chain 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_cdr  * pick_unlocked_cdr ( struct  ast_cdr  * cdr )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_cdr  * cdr_orig  =  cdr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ast_test_flag ( cdr , AST_CDR_FLAG_LOCKED ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  cdr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										cdr  =  cdr - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  cdr_orig ;  /* everybody LOCKED or some other weirdness, like a NULL */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  bridge  the  call  and  set  CDR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  chan , peer , config 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Set  start  time ,  check  for  two  channels , check  if  monitor  on 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  check  for  feature  activation ,  create  new  CDR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  res  on  success . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  - 1  on  failure  to  bridge . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  ast_bridge_call ( struct  ast_channel  * chan , struct  ast_channel  * peer , struct  ast_bridge_config  * config )  
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Copy voice back and forth between the two channels.  Give the peer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   the  ability  to  transfer  calls  with  ' # < extension '  syntax .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_frame  * f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * who ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  chan_featurecode [ FEATURE_MAX_LEN  +  1 ] = " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  peer_featurecode [ FEATURE_MAX_LEN  +  1 ] = " " ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  orig_channame [ AST_MAX_EXTENSION ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  orig_peername [ AST_MAX_EXTENSION ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-06 13:54:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  diff ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  hasfeatures = 0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  hadfeatures = 0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-31 18:55:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  autoloopflag ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  ast_option_header  * aoh ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_bridge_config  backup_config ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_cdr  * bridge_cdr  =  NULL ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 134883 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r134883 | murf | 2008-07-31 13:23:42 -0600 (Thu, 31 Jul 2008) | 51 lines
(closes issue #11849)
Reported by: greyvoip
Tested by: murf
OK, a few days of debugging, a bunch of instrumentation
in chan_sip, main/channel.c, main/pbx.c, etc. and 5 solid 
notebook pages of notes later, I  have made the small
tweek necc. to get the start time right on the second 
CDR when:
  A Calls B
  B answ.
  A hits Xfer button on sip phone,
  A dials C and hits the OK button,
  A hangs up
  C answers ringing phone
  B and C converse
  B and/or C hangs up
But does not harm the scenario where:
  A Calls B
  B answ.
  B hits xfer button on sip phone,
  B dials C and hits the OK button,
  B hangs up
  C answers ringing phone
  A and C converse
  A and/or C hangs up
The difference in start times on the second CDR is because
of a Masquerade on the B channel when the xfer number is 
sent. It ends up replacing the CDR on the B channel with
a duplicate, which ends up getting tossed out. We keep 
a pointer to the first CDR, and update *that* after the
bridge closes. But, only if the CDR has changed.
I hope this change is specific enough not to muck
up any current CDR-based apps. In my defence, I 
assert that the previous information was wrong,
and this change fixes it, and possibly other
similar scenarios.
I wonder if I should be doing the same thing
for the channel, as I did for the peer, but
I can't think of a scenario this might affect.
I leave it, then, as an exersize for the users,
to find the scenario where the chan's CDR 
changes and loses the proper start time.
........
and as to 1.4 to trunk; have I expressed my 
feelings about code shifting from one file
to another? Good.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@134922 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-07-31 19:48:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_cdr  * orig_peer_cdr  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
											
												Merged revisions 142575 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142575 | murf | 2008-09-11 16:55:49 -0600 (Thu, 11 Sep 2008) | 20 lines
(closes issue #13364)
Reported by: mdu113
Well, fundamentally, the problems revealed in 13364 are
because of the ForkCDR call that is done before the dial. 
When the bridge is in place, it's dealing with the first
(and wrong) cdr in the list.
So, I wrote a little func to zip down to the first non-locked
cdr in the chain, and thru-out the ast_bridge_call, these
results are used instead of raw chan->cdr and peer->cdr pointers.
This shouldn't affect anyone who isn't forking cdrs before a
dial, and should correct the cdr's of those that do.
So, this change ends up correcting the dstchannel
and userfield; the disposition was fixed by a previous
patch, it was OK coming into this problem.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-11 23:12:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_cdr  * chan_cdr  =  pick_unlocked_cdr ( chan - > cdr ) ;  /* the proper chan cdr, if there are forked cdrs */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_cdr  * peer_cdr  =  pick_unlocked_cdr ( peer - > cdr ) ;  /* the proper chan cdr, if there are forked cdrs */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-23 16:52:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_cdr  * new_chan_cdr  =  NULL ;  /* the proper chan cdr, if there are forked cdrs */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_cdr  * new_peer_cdr  =  NULL ;  /* the proper chan cdr, if there are forked cdrs */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-09-17 03:49:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									memset ( & backup_config ,  0 ,  sizeof ( backup_config ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-03 04:42:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									config - > start_time  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-10-27 22:01:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( chan  & &  peer )  { 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-28 15:53:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  " BRIDGEPEER " ,  peer - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( peer ,  " BRIDGEPEER " ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  if  ( chan ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-27 22:01:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  " BLINDTRANSFER " ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-09-17 14:15:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( monitor_ok )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-03 19:25:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										const  char  * monitor_exec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_channel  * src  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-09-17 14:15:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! monitor_app )  {  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ( monitor_app  =  pbx_findapp ( " Monitor " ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-09-17 03:49:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												monitor_ok = 0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-09-17 14:15:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ( monitor_exec  =  pbx_builtin_getvar_helper ( chan ,  " AUTO_MONITOR " ) ) )  
							 
						 
					
						
							
								
									
										
										
										
											2005-12-03 19:25:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											src  =  chan ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-09-17 14:15:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										else  if  ( ( monitor_exec  =  pbx_builtin_getvar_helper ( peer ,  " AUTO_MONITOR " ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-03 19:25:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											src  =  peer ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-17 18:20:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( monitor_app  & &  src )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-03 19:25:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											char  * tmp  =  ast_strdupa ( monitor_exec ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-10 13:22:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pbx_exec ( src ,  monitor_app ,  tmp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-03 19:25:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2004-09-17 03:49:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-09-07 21:36:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									set_config_flags ( chan ,  peer ,  config ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-06 14:43:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									config - > firstpass  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-07-02 14:06:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									/* Answer if need be */ 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-02 19:37:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ast_answer ( chan ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-30 14:37:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_copy_string ( orig_channame , chan - > name , sizeof ( orig_channame ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_copy_string ( orig_peername , peer - > name , sizeof ( orig_peername ) ) ; 
							 
						 
					
						
							
								
									
										
										
											
												Merged revisions 142575 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142575 | murf | 2008-09-11 16:55:49 -0600 (Thu, 11 Sep 2008) | 20 lines
(closes issue #13364)
Reported by: mdu113
Well, fundamentally, the problems revealed in 13364 are
because of the ForkCDR call that is done before the dial. 
When the bridge is in place, it's dealing with the first
(and wrong) cdr in the list.
So, I wrote a little func to zip down to the first non-locked
cdr in the chain, and thru-out the ast_bridge_call, these
results are used instead of raw chan->cdr and peer->cdr pointers.
This shouldn't affect anyone who isn't forking cdrs before a
dial, and should correct the cdr's of those that do.
So, this change ends up correcting the dstchannel
and userfield; the disposition was fixed by a previous
patch, it was OK coming into this problem.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-11 23:12:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									orig_peer_cdr  =  peer_cdr ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
											
												Merged revisions 142575 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142575 | murf | 2008-09-11 16:55:49 -0600 (Thu, 11 Sep 2008) | 20 lines
(closes issue #13364)
Reported by: mdu113
Well, fundamentally, the problems revealed in 13364 are
because of the ForkCDR call that is done before the dial. 
When the bridge is in place, it's dealing with the first
(and wrong) cdr in the list.
So, I wrote a little func to zip down to the first non-locked
cdr in the chain, and thru-out the ast_bridge_call, these
results are used instead of raw chan->cdr and peer->cdr pointers.
This shouldn't affect anyone who isn't forking cdrs before a
dial, and should correct the cdr's of those that do.
So, this change ends up correcting the dstchannel
and userfield; the disposition was fixed by a previous
patch, it was OK coming into this problem.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-11 23:12:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! chan_cdr  | |  ( chan_cdr  & &  ! ast_test_flag ( chan_cdr ,  AST_CDR_FLAG_POST_DISABLED ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										
							 
						 
					
						
							
								
									
										
										
											
												Merged revisions 142575 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142575 | murf | 2008-09-11 16:55:49 -0600 (Thu, 11 Sep 2008) | 20 lines
(closes issue #13364)
Reported by: mdu113
Well, fundamentally, the problems revealed in 13364 are
because of the ForkCDR call that is done before the dial. 
When the bridge is in place, it's dealing with the first
(and wrong) cdr in the list.
So, I wrote a little func to zip down to the first non-locked
cdr in the chain, and thru-out the ast_bridge_call, these
results are used instead of raw chan->cdr and peer->cdr pointers.
This shouldn't affect anyone who isn't forking cdrs before a
dial, and should correct the cdr's of those that do.
So, this change ends up correcting the dstchannel
and userfield; the disposition was fixed by a previous
patch, it was OK coming into this problem.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-11 23:12:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( chan_cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_set_flag ( chan_cdr ,  AST_CDR_FLAG_MAIN ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_cdr_update ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
											
												Merged revisions 142575 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142575 | murf | 2008-09-11 16:55:49 -0600 (Thu, 11 Sep 2008) | 20 lines
(closes issue #13364)
Reported by: mdu113
Well, fundamentally, the problems revealed in 13364 are
because of the ForkCDR call that is done before the dial. 
When the bridge is in place, it's dealing with the first
(and wrong) cdr in the list.
So, I wrote a little func to zip down to the first non-locked
cdr in the chain, and thru-out the ast_bridge_call, these
results are used instead of raw chan->cdr and peer->cdr pointers.
This shouldn't affect anyone who isn't forking cdrs before a
dial, and should correct the cdr's of those that do.
So, this change ends up correcting the dstchannel
and userfield; the disposition was fixed by a previous
patch, it was OK coming into this problem.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-11 23:12:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											bridge_cdr  =  ast_cdr_dup ( chan_cdr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_copy_string ( bridge_cdr - > lastapp ,  chan - > appl ,  sizeof ( bridge_cdr - > lastapp ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( bridge_cdr - > lastdata ,  chan - > data ,  sizeof ( bridge_cdr - > lastdata ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* better yet, in a xfer situation, find out why the chan cdr got zapped (pun unintentional) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bridge_cdr  =  ast_cdr_alloc ( ) ;  /* this should be really, really rare/impossible? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( bridge_cdr - > channel ,  chan - > name ,  sizeof ( bridge_cdr - > channel ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( bridge_cdr - > dstchannel ,  peer - > name ,  sizeof ( bridge_cdr - > dstchannel ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( bridge_cdr - > uniqueid ,  chan - > uniqueid ,  sizeof ( bridge_cdr - > uniqueid ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( bridge_cdr - > lastapp ,  chan - > appl ,  sizeof ( bridge_cdr - > lastapp ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( bridge_cdr - > lastdata ,  chan - > data ,  sizeof ( bridge_cdr - > lastdata ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cdr_setcid ( bridge_cdr ,  chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bridge_cdr - > disposition  =  ( chan - > _state  = =  AST_STATE_UP )  ?   AST_CDR_ANSWERED  :  AST_CDR_NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bridge_cdr - > amaflags  =  chan - > amaflags  ?  chan - > amaflags  :   ast_default_amaflags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( bridge_cdr - > accountcode ,  chan - > accountcode ,  sizeof ( bridge_cdr - > accountcode ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Destination information */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( bridge_cdr - > dst ,  chan - > exten ,  sizeof ( bridge_cdr - > dst ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( bridge_cdr - > dcontext ,  chan - > context ,  sizeof ( bridge_cdr - > dcontext ) ) ; 
							 
						 
					
						
							
								
									
										
										
											
												Merged revisions 142575 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142575 | murf | 2008-09-11 16:55:49 -0600 (Thu, 11 Sep 2008) | 20 lines
(closes issue #13364)
Reported by: mdu113
Well, fundamentally, the problems revealed in 13364 are
because of the ForkCDR call that is done before the dial. 
When the bridge is in place, it's dealing with the first
(and wrong) cdr in the list.
So, I wrote a little func to zip down to the first non-locked
cdr in the chain, and thru-out the ast_bridge_call, these
results are used instead of raw chan->cdr and peer->cdr pointers.
This shouldn't affect anyone who isn't forking cdrs before a
dial, and should correct the cdr's of those that do.
So, this change ends up correcting the dstchannel
and userfield; the disposition was fixed by a previous
patch, it was OK coming into this problem.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-11 23:12:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( peer_cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												bridge_cdr - > start  =  peer_cdr - > start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_copy_string ( bridge_cdr - > userfield ,  peer_cdr - > userfield ,  sizeof ( bridge_cdr - > userfield ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_cdr_start ( bridge_cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-07 20:25:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 4 , " bridge answer set, chan answer set \n " ) ; 
							 
						 
					
						
							
								
									
										
										
											
												Merged revisions 142575 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142575 | murf | 2008-09-11 16:55:49 -0600 (Thu, 11 Sep 2008) | 20 lines
(closes issue #13364)
Reported by: mdu113
Well, fundamentally, the problems revealed in 13364 are
because of the ForkCDR call that is done before the dial. 
When the bridge is in place, it's dealing with the first
(and wrong) cdr in the list.
So, I wrote a little func to zip down to the first non-locked
cdr in the chain, and thru-out the ast_bridge_call, these
results are used instead of raw chan->cdr and peer->cdr pointers.
This shouldn't affect anyone who isn't forking cdrs before a
dial, and should correct the cdr's of those that do.
So, this change ends up correcting the dstchannel
and userfield; the disposition was fixed by a previous
patch, it was OK coming into this problem.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-11 23:12:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* peer_cdr->answer will be set when a macro runs on the peer;
 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 135799 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r135799 | murf | 2008-08-05 17:13:20 -0600 (Tue, 05 Aug 2008) | 34 lines
(closes issue #12982)
Reported by: bcnit
Tested by: murf
I discovered that also, in the previous bug fixes and changes,
the cdr.conf 'unanswered' option is not being obeyed, so
I fixed this.
And, yes, there are two 'answer' times involved in this
scenario, and I would agree with you, that the first 
answer time is the time that should appear in the CDR.
(the second 'answer' time is the time that the bridge
was begun).
I made the necessary adjustments, recording the first
answer time into the peer cdr, and then using that to
override the bridge cdr's value.
To get the 'unanswered' CDRs to appear, I purposely
output them, using the dial cmd to mark them as
DIALED (with a new flag), and outputting them if
they bear that flag, and you are in the right mode.
I also corrected one small mention of the Zap device
to equally consider the dahdi device.
I heavily tested 10-sec-wait macros in dial, and
without the macro call; I tested hangups while the
macro was running vs. letting the macro complete
and the bridge form. Looks OK. Removed all the
instrumentation and debug.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@135821 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-08-05 23:45:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										   in  that  case ,  the  bridge  answer  will  be  delayed  while  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   macro  plays  on  the  peer  channel .  The  peer  answered  the  call 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   before  the  macro  started  playing .  To  the  phone  system , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   this  is  billable  time  for  the  call ,  even  tho  the  caller 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   hears  nothing  but  ringing  while  the  macro  does  its  thing .  */ 
							 
						 
					
						
							
								
									
										
										
											
												Merged revisions 142575 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142575 | murf | 2008-09-11 16:55:49 -0600 (Thu, 11 Sep 2008) | 20 lines
(closes issue #13364)
Reported by: mdu113
Well, fundamentally, the problems revealed in 13364 are
because of the ForkCDR call that is done before the dial. 
When the bridge is in place, it's dealing with the first
(and wrong) cdr in the list.
So, I wrote a little func to zip down to the first non-locked
cdr in the chain, and thru-out the ast_bridge_call, these
results are used instead of raw chan->cdr and peer->cdr pointers.
This shouldn't affect anyone who isn't forking cdrs before a
dial, and should correct the cdr's of those that do.
So, this change ends up correcting the dstchannel
and userfield; the disposition was fixed by a previous
patch, it was OK coming into this problem.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-11 23:12:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( peer_cdr  & &  ! ast_tvzero ( peer_cdr - > answer ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bridge_cdr - > answer  =  peer_cdr - > answer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											chan_cdr - > answer  =  peer_cdr - > answer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											bridge_cdr - > disposition  =  peer_cdr - > disposition ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											chan_cdr - > disposition  =  peer_cdr - > disposition ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 135799 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r135799 | murf | 2008-08-05 17:13:20 -0600 (Tue, 05 Aug 2008) | 34 lines
(closes issue #12982)
Reported by: bcnit
Tested by: murf
I discovered that also, in the previous bug fixes and changes,
the cdr.conf 'unanswered' option is not being obeyed, so
I fixed this.
And, yes, there are two 'answer' times involved in this
scenario, and I would agree with you, that the first 
answer time is the time that should appear in the CDR.
(the second 'answer' time is the time that the bridge
was begun).
I made the necessary adjustments, recording the first
answer time into the peer cdr, and then using that to
override the bridge cdr's value.
To get the 'unanswered' CDRs to appear, I purposely
output them, using the dial cmd to mark them as
DIALED (with a new flag), and outputting them if
they bear that flag, and you are in the right mode.
I also corrected one small mention of the Zap device
to equally consider the dahdi device.
I heavily tested 10-sec-wait macros in dial, and
without the macro call; I tested hangups while the
macro was running vs. letting the macro complete
and the bridge form. Looks OK. Removed all the
instrumentation and debug.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@135821 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-08-05 23:45:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cdr_answer ( bridge_cdr ) ; 
							 
						 
					
						
							
								
									
										
										
											
												Merged revisions 142575 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142575 | murf | 2008-09-11 16:55:49 -0600 (Thu, 11 Sep 2008) | 20 lines
(closes issue #13364)
Reported by: mdu113
Well, fundamentally, the problems revealed in 13364 are
because of the ForkCDR call that is done before the dial. 
When the bridge is in place, it's dealing with the first
(and wrong) cdr in the list.
So, I wrote a little func to zip down to the first non-locked
cdr in the chain, and thru-out the ast_bridge_call, these
results are used instead of raw chan->cdr and peer->cdr pointers.
This shouldn't affect anyone who isn't forking cdrs before a
dial, and should correct the cdr's of those that do.
So, this change ends up correcting the dstchannel
and userfield; the disposition was fixed by a previous
patch, it was OK coming into this problem.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-11 23:12:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_cdr_answer ( chan_cdr ) ;  /* for the sake of cli status checks */ 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 135799 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r135799 | murf | 2008-08-05 17:13:20 -0600 (Tue, 05 Aug 2008) | 34 lines
(closes issue #12982)
Reported by: bcnit
Tested by: murf
I discovered that also, in the previous bug fixes and changes,
the cdr.conf 'unanswered' option is not being obeyed, so
I fixed this.
And, yes, there are two 'answer' times involved in this
scenario, and I would agree with you, that the first 
answer time is the time that should appear in the CDR.
(the second 'answer' time is the time that the bridge
was begun).
I made the necessary adjustments, recording the first
answer time into the peer cdr, and then using that to
override the bridge cdr's value.
To get the 'unanswered' CDRs to appear, I purposely
output them, using the dial cmd to mark them as
DIALED (with a new flag), and outputting them if
they bear that flag, and you are in the right mode.
I also corrected one small mention of the Zap device
to equally consider the dahdi device.
I heavily tested 10-sec-wait macros in dial, and
without the macro call; I tested hangups while the
macro was running vs. letting the macro complete
and the bridge form. Looks OK. Removed all the
instrumentation and debug.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@135821 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-08-05 23:45:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
											
												Merged revisions 142575 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142575 | murf | 2008-09-11 16:55:49 -0600 (Thu, 11 Sep 2008) | 20 lines
(closes issue #13364)
Reported by: mdu113
Well, fundamentally, the problems revealed in 13364 are
because of the ForkCDR call that is done before the dial. 
When the bridge is in place, it's dealing with the first
(and wrong) cdr in the list.
So, I wrote a little func to zip down to the first non-locked
cdr in the chain, and thru-out the ast_bridge_call, these
results are used instead of raw chan->cdr and peer->cdr pointers.
This shouldn't affect anyone who isn't forking cdrs before a
dial, and should correct the cdr's of those that do.
So, this change ends up correcting the dstchannel
and userfield; the disposition was fixed by a previous
patch, it was OK coming into this problem.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142576 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-11 23:12:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 		ast_set_flag ( chan_cdr ,  AST_CDR_FLAG_BRIDGED ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( peer_cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 			ast_set_flag ( peer_cdr ,  AST_CDR_FLAG_BRIDGED ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 134883 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r134883 | murf | 2008-07-31 13:23:42 -0600 (Thu, 31 Jul 2008) | 51 lines
(closes issue #11849)
Reported by: greyvoip
Tested by: murf
OK, a few days of debugging, a bunch of instrumentation
in chan_sip, main/channel.c, main/pbx.c, etc. and 5 solid 
notebook pages of notes later, I  have made the small
tweek necc. to get the start time right on the second 
CDR when:
  A Calls B
  B answ.
  A hits Xfer button on sip phone,
  A dials C and hits the OK button,
  A hangs up
  C answers ringing phone
  B and C converse
  B and/or C hangs up
But does not harm the scenario where:
  A Calls B
  B answ.
  B hits xfer button on sip phone,
  B dials C and hits the OK button,
  B hangs up
  C answers ringing phone
  A and C converse
  A and/or C hangs up
The difference in start times on the second CDR is because
of a Masquerade on the B channel when the xfer number is 
sent. It ends up replacing the CDR on the B channel with
a duplicate, which ends up getting tossed out. We keep 
a pointer to the first CDR, and update *that* after the
bridge closes. But, only if the CDR has changed.
I hope this change is specific enough not to muck
up any current CDR-based apps. In my defence, I 
assert that the previous information was wrong,
and this change fixes it, and possibly other
similar scenarios.
I wonder if I should be doing the same thing
for the channel, as I did for the peer, but
I can't think of a scenario this might affect.
I leave it, then, as an exersize for the users,
to find the scenario where the chan's CDR 
changes and loses the proper start time.
........
and as to 1.4 to trunk; have I expressed my 
feelings about code shifting from one file
to another? Good.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@134922 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-07-31 19:48:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 23:20:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  ast_channel  * other ; 	/* used later */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										res  =  ast_channel_bridge ( chan ,  peer ,  config ,  & f ,  & who ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-03 04:42:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( config - > feature_timer )  { 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-06 13:54:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Update time limit for next pass */ 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 43779 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
................
r43779 | russell | 2006-09-27 12:55:49 -0400 (Wed, 27 Sep 2006) | 50 lines
Merged revisions 43778 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2
........
r43778 | russell | 2006-09-27 12:54:30 -0400 (Wed, 27 Sep 2006) | 42 lines
Fix a problem that occurred if a user entered a digit that matched a bridge
feature that was configured using multiple digits, and the digit that was
pressed timed out in the feature digit timeout period.  For example, if blind
transfer is configured as '##', and a user presses just '#'.  In this situation,
the call would lock up and no longer pass any frames.
(issue #7977 reported by festr, and issue #7982 reported by michaels and
 valuable input provided by mneuhauser and kuj.  Fixed by me, with testing help
 and peer review from Joshua Colp).
There are a couple of issues involved in this fix:
1) When ast_generic_bridge determines that there has been a timeout, it returned
   AST_BRIDGE_RETRY.  Then, when ast_channel_bridge gets this result, it calls
   ast_generic_bridge over again with the same timestamp for the next event.
   This results in an endless loop of nothing until the call is terminated.
   This is resolved by simply changing ast_generic_bridge to return 
   AST_BRIDGE_COMPLETE when it sees a timeout.
2) I also changed ast_channel_bridge such that if in the process of calculating
   the time until the next event, it knows a timeout has already occured, to
   immediately return AST_BRIDGE_COMPLETE instead of attempting to bridge the
   channels anyway.
3) In the process of testing the previous two changes, I ran into a problem in
   res_features where ast_channel_bridge would return because it determined
   that there was a timeout.  However, ast_bridge_call in res_features would
   then determine by its own calculation that there was still 1 ms before the
   timeout really occurs.  It would then proceed, and since the bridge broke
   out and did *not* return a frame, it interpreted this as the call was over
   and hung up the channels.
   The reason for this was because ast_bridge_call in res_features and
   ast_channel_bridge in channel.c were using different times for their
   calculations.  channel.c uses the start_time on the bridge config, which
   is the time that the feature digit was recieved.  However, res_features
   had another time, 'start', which was set right before calling 
   ast_channel_bridge.  'start' will always be slightly after start_time in the
   bridge config, and sometimes enough to round up to one ms.
   This is fixed by making ast_bridge_call use the same time as 
   ast_channel_bridge for the timeout calculation.
........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@43780 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-09-27 16:57:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											diff  =  ast_tvdiff_ms ( ast_tvnow ( ) ,  config - > start_time ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-03 04:42:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											config - > feature_timer  - =  diff ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( hasfeatures )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Running on backup config, meaning a feature might be being
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   activated ,  but  that ' s  no  excuse  to  keep  things  going  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   indefinitely !  */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-03 04:42:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( backup_config . feature_timer  & &  ( ( backup_config . feature_timer  - =  diff )  < =  0 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Timed out, realtime this time! \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-03 04:42:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													config - > feature_timer  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													who  =  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													f  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-03 04:42:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  if  ( config - > feature_timer  < =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													/* Not *really* out of time, just out of time for
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													   digits  to  come  in  for  features .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_debug ( 1 ,  " Timed out for feature! \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ! ast_strlen_zero ( peer_featurecode ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-06 21:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_dtmf_stream ( chan ,  peer ,  peer_featurecode ,  0 ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														memset ( peer_featurecode ,  0 ,  sizeof ( peer_featurecode ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( ! ast_strlen_zero ( chan_featurecode ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-06 21:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														ast_dtmf_stream ( peer ,  chan ,  chan_featurecode ,  0 ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														memset ( chan_featurecode ,  0 ,  sizeof ( chan_featurecode ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hasfeatures  =  ! ast_strlen_zero ( chan_featurecode )  | |  ! ast_strlen_zero ( peer_featurecode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( ! hasfeatures )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														/* Restore original (possibly time modified) bridge config */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														memcpy ( config ,  & backup_config ,  sizeof ( struct  ast_bridge_config ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														memset ( & backup_config ,  0 ,  sizeof ( backup_config ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													hadfeatures  =  hasfeatures ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Continue as we were */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 43779 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
................
r43779 | russell | 2006-09-27 12:55:49 -0400 (Wed, 27 Sep 2006) | 50 lines
Merged revisions 43778 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2
........
r43778 | russell | 2006-09-27 12:54:30 -0400 (Wed, 27 Sep 2006) | 42 lines
Fix a problem that occurred if a user entered a digit that matched a bridge
feature that was configured using multiple digits, and the digit that was
pressed timed out in the feature digit timeout period.  For example, if blind
transfer is configured as '##', and a user presses just '#'.  In this situation,
the call would lock up and no longer pass any frames.
(issue #7977 reported by festr, and issue #7982 reported by michaels and
 valuable input provided by mneuhauser and kuj.  Fixed by me, with testing help
 and peer review from Joshua Colp).
There are a couple of issues involved in this fix:
1) When ast_generic_bridge determines that there has been a timeout, it returned
   AST_BRIDGE_RETRY.  Then, when ast_channel_bridge gets this result, it calls
   ast_generic_bridge over again with the same timestamp for the next event.
   This results in an endless loop of nothing until the call is terminated.
   This is resolved by simply changing ast_generic_bridge to return 
   AST_BRIDGE_COMPLETE when it sees a timeout.
2) I also changed ast_channel_bridge such that if in the process of calculating
   the time until the next event, it knows a timeout has already occured, to
   immediately return AST_BRIDGE_COMPLETE instead of attempting to bridge the
   channels anyway.
3) In the process of testing the previous two changes, I ran into a problem in
   res_features where ast_channel_bridge would return because it determined
   that there was a timeout.  However, ast_bridge_call in res_features would
   then determine by its own calculation that there was still 1 ms before the
   timeout really occurs.  It would then proceed, and since the bridge broke
   out and did *not* return a frame, it interpreted this as the call was over
   and hung up the channels.
   The reason for this was because ast_bridge_call in res_features and
   ast_channel_bridge in channel.c were using different times for their
   calculations.  channel.c uses the start_time on the bridge config, which
   is the time that the feature digit was recieved.  However, res_features
   had another time, 'start', which was set right before calling 
   ast_channel_bridge.  'start' will always be slightly after start_time in the
   bridge config, and sometimes enough to round up to one ms.
   This is fixed by making ast_bridge_call use the same time as 
   ast_channel_bridge for the timeout calculation.
........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@43780 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-09-27 16:57:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  if  ( ! f )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* The bridge returned without a frame and there is a feature in progress.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  However ,  we  don ' t  think  the  feature  has  quite  yet  timed  out ,  so  just 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													 *  go  back  into  the  bridge .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 				} 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-03 04:42:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( config - > feature_timer  < = 0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													/* We ran out of time */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-03 04:42:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													config - > feature_timer  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													who  =  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													f  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-06 13:54:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										if  ( res  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-30 16:15:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! ast_test_flag ( chan ,  AST_FLAG_ZOMBIE )  & &  ! ast_test_flag ( peer ,  AST_FLAG_ZOMBIE )  & &  ! ast_check_hangup ( chan )  & &  ! ast_check_hangup ( peer ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Bridge failed on channels %s and %s \n " ,  chan - > name ,  peer - > name ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 135799 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r135799 | murf | 2008-08-05 17:13:20 -0600 (Tue, 05 Aug 2008) | 34 lines
(closes issue #12982)
Reported by: bcnit
Tested by: murf
I discovered that also, in the previous bug fixes and changes,
the cdr.conf 'unanswered' option is not being obeyed, so
I fixed this.
And, yes, there are two 'answer' times involved in this
scenario, and I would agree with you, that the first 
answer time is the time that should appear in the CDR.
(the second 'answer' time is the time that the bridge
was begun).
I made the necessary adjustments, recording the first
answer time into the peer cdr, and then using that to
override the bridge cdr's value.
To get the 'unanswered' CDRs to appear, I purposely
output them, using the dial cmd to mark them as
DIALED (with a new flag), and outputting them if
they bear that flag, and you are in the right mode.
I also corrected one small mention of the Zap device
to equally consider the dahdi device.
I heavily tested 10-sec-wait macros in dial, and
without the macro call; I tested hangups while the
macro was running vs. letting the macro complete
and the bridge form. Looks OK. Removed all the
instrumentation and debug.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@135821 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-08-05 23:45:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											goto  before_you_go ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 18:37:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! f  | |  ( f - > frametype  = =  AST_FRAME_CONTROL  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												( f - > subclass  = =  AST_CONTROL_HANGUP  | |  f - > subclass  = =  AST_CONTROL_BUSY  | |  
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													f - > subclass  = =  AST_CONTROL_CONGESTION ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 18:37:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 23:20:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* many things should be sent to the 'other' channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										other  =  ( who  = =  chan )  ?  peer  :  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( f - > frametype  = =  AST_FRAME_CONTROL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-05 20:51:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											switch  ( f - > subclass )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  AST_CONTROL_RINGING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  AST_CONTROL_FLASH : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  - 1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_indicate ( other ,  f - > subclass ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  AST_CONTROL_HOLD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  AST_CONTROL_UNHOLD : 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-22 16:29:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_indicate_data ( other ,  f - > subclass ,  f - > data . ptr ,  f - > datalen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-05 20:51:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											case  AST_CONTROL_OPTION : 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-22 16:29:54 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												aoh  =  f - > data . ptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 23:20:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Forward option Requests */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-05 20:51:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( aoh  & &  aoh - > flag  = =  AST_OPTION_FLAG_REQUEST )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_channel_setoption ( other ,  ntohs ( aoh - > option ) ,  aoh - > data ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														f - > datalen  -  sizeof ( struct  ast_option_header ) ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( f - > frametype  = =  AST_FRAME_DTMF_BEGIN )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* eat it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( f - > frametype  = =  AST_FRAME_DTMF )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											char  * featurecode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											int  sense ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											hadfeatures  =  hasfeatures ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* This cannot overrun because the longest feature is one shorter than our buffer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( who  = =  chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sense  =  FEATURE_SENSE_CHAN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												featurecode  =  chan_featurecode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else   { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												sense  =  FEATURE_SENSE_PEER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												featurecode  =  peer_featurecode ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-17 04:31:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/*! append the event to featurecode. we rely on the string being zero-filled, and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  not  overflowing  it .  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 *  \ todo  XXX  how  do  we  guarantee  the  latter  ? 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 23:20:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											featurecode [ strlen ( featurecode ) ]  =  f - > subclass ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-23 16:37:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Get rid of the frame before we start doing "stuff" with the channels */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											f  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-03 04:42:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											config - > feature_timer  =  backup_config . feature_timer ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											res  =  ast_feature_interpret ( chan ,  peer ,  config ,  featurecode ,  sense ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											switch ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											case  AST_FEATURE_RETURN_PASSDIGITS : 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-06 21:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_dtmf_stream ( other ,  who ,  featurecode ,  0 ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Fall through */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											case  AST_FEATURE_RETURN_SUCCESS : 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												memset ( featurecode ,  0 ,  sizeof ( chan_featurecode ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-08 17:32:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( res  > =  AST_FEATURE_RETURN_PASSDIGITS )  { 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
												res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-23 16:37:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											hasfeatures  =  ! ast_strlen_zero ( chan_featurecode )  | |  ! ast_strlen_zero ( peer_featurecode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( hadfeatures  & &  ! hasfeatures )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Restore backup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												memcpy ( config ,  & backup_config ,  sizeof ( struct  ast_bridge_config ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												memset ( & backup_config ,  0 ,  sizeof ( struct  ast_bridge_config ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  if  ( hasfeatures )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! hadfeatures )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Backup configuration */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													memcpy ( & backup_config ,  config ,  sizeof ( struct  ast_bridge_config ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* Setup temporary config options */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													config - > play_warning  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 14:46:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_clear_flag ( & ( config - > features_caller ) ,  AST_FEATURE_PLAY_WARNING ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_clear_flag ( & ( config - > features_callee ) ,  AST_FEATURE_PLAY_WARNING ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													config - > warning_freq  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													config - > warning_sound  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													config - > end_sound  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													config - > start_sound  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													config - > firstpass  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-01 23:09:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												config - > start_time  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-03 04:42:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												config - > feature_timer  =  featuredigittimeout ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Set time limit to %ld \n " ,  config - > feature_timer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-10 05:41:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 135799 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r135799 | murf | 2008-08-05 17:13:20 -0600 (Tue, 05 Aug 2008) | 34 lines
(closes issue #12982)
Reported by: bcnit
Tested by: murf
I discovered that also, in the previous bug fixes and changes,
the cdr.conf 'unanswered' option is not being obeyed, so
I fixed this.
And, yes, there are two 'answer' times involved in this
scenario, and I would agree with you, that the first 
answer time is the time that should appear in the CDR.
(the second 'answer' time is the time that the bridge
was begun).
I made the necessary adjustments, recording the first
answer time into the peer cdr, and then using that to
override the bridge cdr's value.
To get the 'unanswered' CDRs to appear, I purposely
output them, using the dial cmd to mark them as
DIALED (with a new flag), and outputting them if
they bear that flag, and you are in the right mode.
I also corrected one small mention of the Zap device
to equally consider the dahdi device.
I heavily tested 10-sec-wait macros in dial, and
without the macro call; I tested hangups while the
macro was running vs. letting the macro complete
and the bridge form. Looks OK. Removed all the
instrumentation and debug.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@135821 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-08-05 23:45:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   before_you_go : 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-31 18:55:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res  ! =  AST_PBX_KEEPALIVE  & &  config - > end_bridge_callback )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-09 01:27:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										config - > end_bridge_callback ( config - > end_bridge_callback_data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-31 18:55:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-23 16:52:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 152535 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r152535 | murf | 2008-10-28 22:36:32 -0600 (Tue, 28 Oct 2008) | 46 lines
The magic trick to avoid this crash is not to
try to find the channel by name in the list,
which is slow and resource consuming, but rather
to pay attention to the result codes from the
ast_bridge_call, to which I added the 
AST_PBX_NO_HANGUP_PEER_PARKED value, which
now are returned when a channel is parked.
Why? because CDR's aren't generated via parking,
so nothing is needed, but if a transfer occurred,
there are critical things I need.
If you get AST_PBX_KEEPALIVE,
then don't touch the channel pointer.
If you get AST_PBX_NO_HANGUP_PEER, or
AST_PBX_NO_HANGUP_PEER_PARKED, then don't
touch the peer pointer.
Updated the several places where the results
from a bridge were not being properly obeyed,
and fixed some code I had introduced so that
the results of the bridge were not overridden 
(in trunk).
All the places that previously tested for 
AST_PBX_NO_HANGUP_PEER now have to check for
both AST_PBX_NO_HANGUP_PEER and AST_PBX_NO_HANGUP_PEER_PARKED.
I tested this against the 4 common parking
scenarios:
1. A calls B; B answers; A parks B; B hangs up while A is getting the parking
slot announcement, immediately after being put on hold.
2. A calls B; B answers; A parks B; B hangs up after A has been hung up, but
before the park times out.
3. A calls B; B answers; B parks A; A hangs up while B is getting the parking slot announcement, immediately after being put on hold.
4. A calls B; B answers; B parks A; A hangs up after B has been hung up, but before the park times out.
No crash.
I also ran the scenarios above against valgrind, and accesses looked good.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@152536 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-10-29 05:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* run the hangup exten on the chan object IFF it was NOT involved in a parking situation 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  if  it  were ,  then  chan  belongs  to  a  different  thread  now ,  and  might  have  been  hung  up  long 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								     *  ago . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-31 18:55:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									autoloopflag  =  ast_test_flag ( chan ,  AST_FLAG_IN_AUTOLOOP ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_set_flag ( chan ,  AST_FLAG_IN_AUTOLOOP ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 152535 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r152535 | murf | 2008-10-28 22:36:32 -0600 (Tue, 28 Oct 2008) | 46 lines
The magic trick to avoid this crash is not to
try to find the channel by name in the list,
which is slow and resource consuming, but rather
to pay attention to the result codes from the
ast_bridge_call, to which I added the 
AST_PBX_NO_HANGUP_PEER_PARKED value, which
now are returned when a channel is parked.
Why? because CDR's aren't generated via parking,
so nothing is needed, but if a transfer occurred,
there are critical things I need.
If you get AST_PBX_KEEPALIVE,
then don't touch the channel pointer.
If you get AST_PBX_NO_HANGUP_PEER, or
AST_PBX_NO_HANGUP_PEER_PARKED, then don't
touch the peer pointer.
Updated the several places where the results
from a bridge were not being properly obeyed,
and fixed some code I had introduced so that
the results of the bridge were not overridden 
(in trunk).
All the places that previously tested for 
AST_PBX_NO_HANGUP_PEER now have to check for
both AST_PBX_NO_HANGUP_PEER and AST_PBX_NO_HANGUP_PEER_PARKED.
I tested this against the 4 common parking
scenarios:
1. A calls B; B answers; A parks B; B hangs up while A is getting the parking
slot announcement, immediately after being put on hold.
2. A calls B; B answers; A parks B; B hangs up after A has been hung up, but
before the park times out.
3. A calls B; B answers; B parks A; A hangs up while B is getting the parking slot announcement, immediately after being put on hold.
4. A calls B; B answers; B parks A; A hangs up after B has been hung up, but before the park times out.
No crash.
I also ran the scenarios above against valgrind, and accesses looked good.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@152536 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-10-29 05:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( res  ! =  AST_PBX_KEEPALIVE  & &  ! ast_test_flag ( & ( config - > features_caller ) , AST_FEATURE_NO_H_EXTEN )  & &  ast_exists_extension ( chan ,  chan - > context ,  " h " ,  1 ,  chan - > cid . cid_num ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-21 23:40:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  ast_cdr  * swapper  =  NULL ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 142675 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142675 | murf | 2008-09-11 22:29:34 -0600 (Thu, 11 Sep 2008) | 29 lines
Tested by: sergee, murf, chris-mac, andrew, KNK
This is a "second attempt" to restore the previous "endbeforeh" behavior
in 1.4 and up. In order to capture information concerning all the
legs of transfers in all their infinite combinations, I was forced
to this particular solution by a chain of logical necessities, the
first being that I was not allowed to rewrite the CDR mechanism from 
the ground up!
This change basically leaves the original machinery alone, which allows
IVR and local channel type situations to generate CDR's as normal, but
a channel flag can be set to suppress the normal running of the h exten.
That flag would be set by the code that runs the h exten from the
ast_bridge_call routine, to prevent the h exten from being run twice.
Also, a flag in the ast_bridge_config struct passed into ast_bridge_call
can be used to suppress the running of the h exten in that routine. This
would happen, for instance, if you use the 'g' option in the Dial app.
Running this routine 'early' allows not only the CDR() func to be used
in the h extension for reading CDR variables, but also allows them to
be modified before the CDR is posted to the backends.
While I dearly hope that this patch overcomes all problems, and 
introduces no new problems, reality suggests that surely someone
will have problems. In this case, please re-open 13251 (or 13289),
and we'll see if we can't fix any remaining issues.
** trunk note: some code to suppress the h exten being run 
from app_queue was added; for the 'continue' option available
only in trunk/1.6.x.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142676 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-12 04:50:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										char  savelastapp [ AST_MAX_EXTENSION ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  savelastdata [ AST_MAX_EXTENSION ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  save_exten [ AST_MAX_EXTENSION ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int   save_prio ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int   found  =  0 ; 	/* set if we find at least one match */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-09 23:15:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int   spawn_error  =  0 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 142675 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142675 | murf | 2008-09-11 22:29:34 -0600 (Thu, 11 Sep 2008) | 29 lines
Tested by: sergee, murf, chris-mac, andrew, KNK
This is a "second attempt" to restore the previous "endbeforeh" behavior
in 1.4 and up. In order to capture information concerning all the
legs of transfers in all their infinite combinations, I was forced
to this particular solution by a chain of logical necessities, the
first being that I was not allowed to rewrite the CDR mechanism from 
the ground up!
This change basically leaves the original machinery alone, which allows
IVR and local channel type situations to generate CDR's as normal, but
a channel flag can be set to suppress the normal running of the h exten.
That flag would be set by the code that runs the h exten from the
ast_bridge_call routine, to prevent the h exten from being run twice.
Also, a flag in the ast_bridge_config struct passed into ast_bridge_call
can be used to suppress the running of the h exten in that routine. This
would happen, for instance, if you use the 'g' option in the Dial app.
Running this routine 'early' allows not only the CDR() func to be used
in the h extension for reading CDR variables, but also allows them to
be modified before the CDR is posted to the backends.
While I dearly hope that this patch overcomes all problems, and 
introduces no new problems, reality suggests that surely someone
will have problems. In this case, please re-open 13251 (or 13289),
and we'll see if we can't fix any remaining issues.
** trunk note: some code to suppress the h exten being run 
from app_queue was added; for the 'continue' option available
only in trunk/1.6.x.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142676 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-12 04:50:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										
							 
						 
					
						
							
								
									
										
										
										
											2008-11-21 23:40:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bridge_cdr  & &  ast_opt_end_cdr_before_h_exten )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 142675 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142675 | murf | 2008-09-11 22:29:34 -0600 (Thu, 11 Sep 2008) | 29 lines
Tested by: sergee, murf, chris-mac, andrew, KNK
This is a "second attempt" to restore the previous "endbeforeh" behavior
in 1.4 and up. In order to capture information concerning all the
legs of transfers in all their infinite combinations, I was forced
to this particular solution by a chain of logical necessities, the
first being that I was not allowed to rewrite the CDR mechanism from 
the ground up!
This change basically leaves the original machinery alone, which allows
IVR and local channel type situations to generate CDR's as normal, but
a channel flag can be set to suppress the normal running of the h exten.
That flag would be set by the code that runs the h exten from the
ast_bridge_call routine, to prevent the h exten from being run twice.
Also, a flag in the ast_bridge_config struct passed into ast_bridge_call
can be used to suppress the running of the h exten in that routine. This
would happen, for instance, if you use the 'g' option in the Dial app.
Running this routine 'early' allows not only the CDR() func to be used
in the h extension for reading CDR variables, but also allows them to
be modified before the CDR is posted to the backends.
While I dearly hope that this patch overcomes all problems, and 
introduces no new problems, reality suggests that surely someone
will have problems. In this case, please re-open 13251 (or 13289),
and we'll see if we can't fix any remaining issues.
** trunk note: some code to suppress the h exten being run 
from app_queue was added; for the 'continue' option available
only in trunk/1.6.x.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142676 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-12 04:50:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_cdr_end ( bridge_cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* swap the bridge cdr and the chan cdr for a moment, and let the endbridge
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   dialplan  code  operate  on  it  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-21 23:40:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bridge_cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											swapper  =  chan - > cdr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( savelastapp ,  bridge_cdr - > lastapp ,  sizeof ( bridge_cdr - > lastapp ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( savelastdata ,  bridge_cdr - > lastdata ,  sizeof ( bridge_cdr - > lastdata ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											chan - > cdr  =  bridge_cdr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 142675 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142675 | murf | 2008-09-11 22:29:34 -0600 (Thu, 11 Sep 2008) | 29 lines
Tested by: sergee, murf, chris-mac, andrew, KNK
This is a "second attempt" to restore the previous "endbeforeh" behavior
in 1.4 and up. In order to capture information concerning all the
legs of transfers in all their infinite combinations, I was forced
to this particular solution by a chain of logical necessities, the
first being that I was not allowed to rewrite the CDR mechanism from 
the ground up!
This change basically leaves the original machinery alone, which allows
IVR and local channel type situations to generate CDR's as normal, but
a channel flag can be set to suppress the normal running of the h exten.
That flag would be set by the code that runs the h exten from the
ast_bridge_call routine, to prevent the h exten from being run twice.
Also, a flag in the ast_bridge_config struct passed into ast_bridge_call
can be used to suppress the running of the h exten in that routine. This
would happen, for instance, if you use the 'g' option in the Dial app.
Running this routine 'early' allows not only the CDR() func to be used
in the h extension for reading CDR variables, but also allows them to
be modified before the CDR is posted to the backends.
While I dearly hope that this patch overcomes all problems, and 
introduces no new problems, reality suggests that surely someone
will have problems. In this case, please re-open 13251 (or 13289),
and we'll see if we can't fix any remaining issues.
** trunk note: some code to suppress the h exten being run 
from app_queue was added; for the 'continue' option available
only in trunk/1.6.x.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142676 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-12 04:50:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_copy_string ( save_exten ,  chan - > exten ,  sizeof ( save_exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										save_prio  =  chan - > priority ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( chan - > exten ,  " h " ,  sizeof ( chan - > exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										chan - > priority  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-09 23:15:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										while  ( ( spawn_error  =  ast_spawn_extension ( chan ,  chan - > context ,  chan - > exten ,  chan - > priority ,  chan - > cid . cid_num ,  & found ,  1 ) )  = =  0 )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 142675 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142675 | murf | 2008-09-11 22:29:34 -0600 (Thu, 11 Sep 2008) | 29 lines
Tested by: sergee, murf, chris-mac, andrew, KNK
This is a "second attempt" to restore the previous "endbeforeh" behavior
in 1.4 and up. In order to capture information concerning all the
legs of transfers in all their infinite combinations, I was forced
to this particular solution by a chain of logical necessities, the
first being that I was not allowed to rewrite the CDR mechanism from 
the ground up!
This change basically leaves the original machinery alone, which allows
IVR and local channel type situations to generate CDR's as normal, but
a channel flag can be set to suppress the normal running of the h exten.
That flag would be set by the code that runs the h exten from the
ast_bridge_call routine, to prevent the h exten from being run twice.
Also, a flag in the ast_bridge_config struct passed into ast_bridge_call
can be used to suppress the running of the h exten in that routine. This
would happen, for instance, if you use the 'g' option in the Dial app.
Running this routine 'early' allows not only the CDR() func to be used
in the h extension for reading CDR variables, but also allows them to
be modified before the CDR is posted to the backends.
While I dearly hope that this patch overcomes all problems, and 
introduces no new problems, reality suggests that surely someone
will have problems. In this case, please re-open 13251 (or 13289),
and we'll see if we can't fix any remaining issues.
** trunk note: some code to suppress the h exten being run 
from app_queue was added; for the 'continue' option available
only in trunk/1.6.x.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142676 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-12 04:50:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											chan - > priority + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-09 23:15:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( found  & &  spawn_error )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 142675 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142675 | murf | 2008-09-11 22:29:34 -0600 (Thu, 11 Sep 2008) | 29 lines
Tested by: sergee, murf, chris-mac, andrew, KNK
This is a "second attempt" to restore the previous "endbeforeh" behavior
in 1.4 and up. In order to capture information concerning all the
legs of transfers in all their infinite combinations, I was forced
to this particular solution by a chain of logical necessities, the
first being that I was not allowed to rewrite the CDR mechanism from 
the ground up!
This change basically leaves the original machinery alone, which allows
IVR and local channel type situations to generate CDR's as normal, but
a channel flag can be set to suppress the normal running of the h exten.
That flag would be set by the code that runs the h exten from the
ast_bridge_call routine, to prevent the h exten from being run twice.
Also, a flag in the ast_bridge_config struct passed into ast_bridge_call
can be used to suppress the running of the h exten in that routine. This
would happen, for instance, if you use the 'g' option in the Dial app.
Running this routine 'early' allows not only the CDR() func to be used
in the h extension for reading CDR variables, but also allows them to
be modified before the CDR is posted to the backends.
While I dearly hope that this patch overcomes all problems, and 
introduces no new problems, reality suggests that surely someone
will have problems. In this case, please re-open 13251 (or 13289),
and we'll see if we can't fix any remaining issues.
** trunk note: some code to suppress the h exten being run 
from app_queue was added; for the 'continue' option available
only in trunk/1.6.x.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142676 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-12 04:50:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Something bad happened, or a hangup has been requested. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " Spawn extension (%s,%s,%d) exited non-zero on '%s' \n " ,  chan - > context ,  chan - > exten ,  chan - > priority ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verb ( 2 ,  " Spawn extension (%s, %s, %d) exited non-zero on '%s' \n " ,  chan - > context ,  chan - > exten ,  chan - > priority ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* swap it back */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( chan - > exten ,  save_exten ,  sizeof ( chan - > exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										chan - > priority  =  save_prio ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-21 23:40:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bridge_cdr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											chan - > cdr  =  swapper ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 142675 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142675 | murf | 2008-09-11 22:29:34 -0600 (Thu, 11 Sep 2008) | 29 lines
Tested by: sergee, murf, chris-mac, andrew, KNK
This is a "second attempt" to restore the previous "endbeforeh" behavior
in 1.4 and up. In order to capture information concerning all the
legs of transfers in all their infinite combinations, I was forced
to this particular solution by a chain of logical necessities, the
first being that I was not allowed to rewrite the CDR mechanism from 
the ground up!
This change basically leaves the original machinery alone, which allows
IVR and local channel type situations to generate CDR's as normal, but
a channel flag can be set to suppress the normal running of the h exten.
That flag would be set by the code that runs the h exten from the
ast_bridge_call routine, to prevent the h exten from being run twice.
Also, a flag in the ast_bridge_config struct passed into ast_bridge_call
can be used to suppress the running of the h exten in that routine. This
would happen, for instance, if you use the 'g' option in the Dial app.
Running this routine 'early' allows not only the CDR() func to be used
in the h extension for reading CDR variables, but also allows them to
be modified before the CDR is posted to the backends.
While I dearly hope that this patch overcomes all problems, and 
introduces no new problems, reality suggests that surely someone
will have problems. In this case, please re-open 13251 (or 13289),
and we'll see if we can't fix any remaining issues.
** trunk note: some code to suppress the h exten being run 
from app_queue was added; for the 'continue' option available
only in trunk/1.6.x.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142676 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-12 04:50:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_set_flag ( chan ,  AST_FLAG_BRIDGE_HANGUP_RUN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* protect the lastapp/lastdata against the effects of the hangup/dialplan code */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-21 23:40:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bridge_cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( bridge_cdr - > lastapp ,  savelastapp ,  sizeof ( bridge_cdr - > lastapp ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( bridge_cdr - > lastdata ,  savelastdata ,  sizeof ( bridge_cdr - > lastdata ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 142675 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142675 | murf | 2008-09-11 22:29:34 -0600 (Thu, 11 Sep 2008) | 29 lines
Tested by: sergee, murf, chris-mac, andrew, KNK
This is a "second attempt" to restore the previous "endbeforeh" behavior
in 1.4 and up. In order to capture information concerning all the
legs of transfers in all their infinite combinations, I was forced
to this particular solution by a chain of logical necessities, the
first being that I was not allowed to rewrite the CDR mechanism from 
the ground up!
This change basically leaves the original machinery alone, which allows
IVR and local channel type situations to generate CDR's as normal, but
a channel flag can be set to suppress the normal running of the h exten.
That flag would be set by the code that runs the h exten from the
ast_bridge_call routine, to prevent the h exten from being run twice.
Also, a flag in the ast_bridge_config struct passed into ast_bridge_call
can be used to suppress the running of the h exten in that routine. This
would happen, for instance, if you use the 'g' option in the Dial app.
Running this routine 'early' allows not only the CDR() func to be used
in the h extension for reading CDR variables, but also allows them to
be modified before the CDR is posted to the backends.
While I dearly hope that this patch overcomes all problems, and 
introduces no new problems, reality suggests that surely someone
will have problems. In this case, please re-open 13251 (or 13289),
and we'll see if we can't fix any remaining issues.
** trunk note: some code to suppress the h exten being run 
from app_queue was added; for the 'continue' option available
only in trunk/1.6.x.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142676 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-12 04:50:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-31 18:55:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_set2_flag ( chan ,  autoloopflag ,  AST_FLAG_IN_AUTOLOOP ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 142675 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r142675 | murf | 2008-09-11 22:29:34 -0600 (Thu, 11 Sep 2008) | 29 lines
Tested by: sergee, murf, chris-mac, andrew, KNK
This is a "second attempt" to restore the previous "endbeforeh" behavior
in 1.4 and up. In order to capture information concerning all the
legs of transfers in all their infinite combinations, I was forced
to this particular solution by a chain of logical necessities, the
first being that I was not allowed to rewrite the CDR mechanism from 
the ground up!
This change basically leaves the original machinery alone, which allows
IVR and local channel type situations to generate CDR's as normal, but
a channel flag can be set to suppress the normal running of the h exten.
That flag would be set by the code that runs the h exten from the
ast_bridge_call routine, to prevent the h exten from being run twice.
Also, a flag in the ast_bridge_config struct passed into ast_bridge_call
can be used to suppress the running of the h exten in that routine. This
would happen, for instance, if you use the 'g' option in the Dial app.
Running this routine 'early' allows not only the CDR() func to be used
in the h extension for reading CDR variables, but also allows them to
be modified before the CDR is posted to the backends.
While I dearly hope that this patch overcomes all problems, and 
introduces no new problems, reality suggests that surely someone
will have problems. In this case, please re-open 13251 (or 13289),
and we'll see if we can't fix any remaining issues.
** trunk note: some code to suppress the h exten being run 
from app_queue was added; for the 'continue' option available
only in trunk/1.6.x.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@142676 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-09-12 04:50:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 152535 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r152535 | murf | 2008-10-28 22:36:32 -0600 (Tue, 28 Oct 2008) | 46 lines
The magic trick to avoid this crash is not to
try to find the channel by name in the list,
which is slow and resource consuming, but rather
to pay attention to the result codes from the
ast_bridge_call, to which I added the 
AST_PBX_NO_HANGUP_PEER_PARKED value, which
now are returned when a channel is parked.
Why? because CDR's aren't generated via parking,
so nothing is needed, but if a transfer occurred,
there are critical things I need.
If you get AST_PBX_KEEPALIVE,
then don't touch the channel pointer.
If you get AST_PBX_NO_HANGUP_PEER, or
AST_PBX_NO_HANGUP_PEER_PARKED, then don't
touch the peer pointer.
Updated the several places where the results
from a bridge were not being properly obeyed,
and fixed some code I had introduced so that
the results of the bridge were not overridden 
(in trunk).
All the places that previously tested for 
AST_PBX_NO_HANGUP_PEER now have to check for
both AST_PBX_NO_HANGUP_PEER and AST_PBX_NO_HANGUP_PEER_PARKED.
I tested this against the 4 common parking
scenarios:
1. A calls B; B answers; A parks B; B hangs up while A is getting the parking
slot announcement, immediately after being put on hold.
2. A calls B; B answers; A parks B; B hangs up after A has been hung up, but
before the park times out.
3. A calls B; B answers; B parks A; A hangs up while B is getting the parking slot announcement, immediately after being put on hold.
4. A calls B; B answers; B parks A; A hangs up after B has been hung up, but before the park times out.
No crash.
I also ran the scenarios above against valgrind, and accesses looked good.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@152536 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-10-29 05:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* obey the NoCDR() wishes. -- move the DISABLED flag to the bridge CDR if it was set on the channel during the bridge... */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  ! =  AST_PBX_KEEPALIVE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_chan_cdr  =  pick_unlocked_cdr ( chan - > cdr ) ;  /* the proper chan cdr, if there are forked cdrs */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-21 21:47:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( bridge_cdr  & &  new_chan_cdr  & &  ast_test_flag ( new_chan_cdr ,  AST_CDR_FLAG_POST_DISABLED ) ) 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 152535 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r152535 | murf | 2008-10-28 22:36:32 -0600 (Tue, 28 Oct 2008) | 46 lines
The magic trick to avoid this crash is not to
try to find the channel by name in the list,
which is slow and resource consuming, but rather
to pay attention to the result codes from the
ast_bridge_call, to which I added the 
AST_PBX_NO_HANGUP_PEER_PARKED value, which
now are returned when a channel is parked.
Why? because CDR's aren't generated via parking,
so nothing is needed, but if a transfer occurred,
there are critical things I need.
If you get AST_PBX_KEEPALIVE,
then don't touch the channel pointer.
If you get AST_PBX_NO_HANGUP_PEER, or
AST_PBX_NO_HANGUP_PEER_PARKED, then don't
touch the peer pointer.
Updated the several places where the results
from a bridge were not being properly obeyed,
and fixed some code I had introduced so that
the results of the bridge were not overridden 
(in trunk).
All the places that previously tested for 
AST_PBX_NO_HANGUP_PEER now have to check for
both AST_PBX_NO_HANGUP_PEER and AST_PBX_NO_HANGUP_PEER_PARKED.
I tested this against the 4 common parking
scenarios:
1. A calls B; B answers; A parks B; B hangs up while A is getting the parking
slot announcement, immediately after being put on hold.
2. A calls B; B answers; A parks B; B hangs up after A has been hung up, but
before the park times out.
3. A calls B; B answers; B parks A; A hangs up while B is getting the parking slot announcement, immediately after being put on hold.
4. A calls B; B answers; B parks A; A hangs up after B has been hung up, but before the park times out.
No crash.
I also ran the scenarios above against valgrind, and accesses looked good.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@152536 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-10-29 05:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_set_flag ( bridge_cdr ,  AST_CDR_FLAG_POST_DISABLED ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* we can post the bridge CDR at this point */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-21 21:47:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( bridge_cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cdr_end ( bridge_cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cdr_detach ( bridge_cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 152535 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r152535 | murf | 2008-10-28 22:36:32 -0600 (Tue, 28 Oct 2008) | 46 lines
The magic trick to avoid this crash is not to
try to find the channel by name in the list,
which is slow and resource consuming, but rather
to pay attention to the result codes from the
ast_bridge_call, to which I added the 
AST_PBX_NO_HANGUP_PEER_PARKED value, which
now are returned when a channel is parked.
Why? because CDR's aren't generated via parking,
so nothing is needed, but if a transfer occurred,
there are critical things I need.
If you get AST_PBX_KEEPALIVE,
then don't touch the channel pointer.
If you get AST_PBX_NO_HANGUP_PEER, or
AST_PBX_NO_HANGUP_PEER_PARKED, then don't
touch the peer pointer.
Updated the several places where the results
from a bridge were not being properly obeyed,
and fixed some code I had introduced so that
the results of the bridge were not overridden 
(in trunk).
All the places that previously tested for 
AST_PBX_NO_HANGUP_PEER now have to check for
both AST_PBX_NO_HANGUP_PEER and AST_PBX_NO_HANGUP_PEER_PARKED.
I tested this against the 4 common parking
scenarios:
1. A calls B; B answers; A parks B; B hangs up while A is getting the parking
slot announcement, immediately after being put on hold.
2. A calls B; B answers; A parks B; B hangs up after A has been hung up, but
before the park times out.
3. A calls B; B answers; B parks A; A hangs up while B is getting the parking slot announcement, immediately after being put on hold.
4. A calls B; B answers; B parks A; A hangs up after B has been hung up, but before the park times out.
No crash.
I also ran the scenarios above against valgrind, and accesses looked good.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@152536 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-10-29 05:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* do a specialized reset on the beginning channel
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   CDR ' s ,  if  they  still  exist ,  so  as  not  to  mess  up 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   issues  in  future  bridges ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   Here  are  the  rules  of  the  game : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   1.  The  chan  and  peer  channel  pointers  will  not  change 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      during  the  life  of  the  bridge . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   2.  But ,  in  transfers ,  the  channel  names  will  change . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      between  the  time  the  bridge  is  started ,  and  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      time  the  channel  ends .  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      Usually ,  when  a  channel  changes  names ,  it  will 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      also  change  CDR  pointers . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   3.  Usually ,  only  one  of  the  two  channels  ( chan  or  peer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      will  change  names . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   4.  Usually ,  if  a  channel  changes  names  during  a  bridge , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      it  is  because  of  a  transfer .  Usually ,  in  these  situations , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      it  is  normal  to  see  2  bridges  running  simultaneously ,  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      it  is  not  unusual  to  see  the  two  channels  that  change 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      swapped  between  bridges . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   5.  After  a  bridge  occurs ,  we  have  2  or  3  channels '  CDRs 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      to  attend  to ;  if  the  chan  or  peer  changed  names , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      we  have  the  before  and  after  attached  CDR ' s . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   6.  Parking  has  to  be  accounted  for  in  the  code : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      a .  Parking  will  cause  ast_bridge_call  to  return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									         either  AST_PBX_NO_HANGUP_PEER  or  AST_PBX_NO_HANGUP_PEER_PARKED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 in  the  latter  case ,  peer  is  ( most  likely )  a  bad 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 pointer ,  you  can  no  longer  deref  it .  If  it  does  still 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 exist ,  it  is  under  another ' s  thread  control ,  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 could  be  destroyed  at  any  time . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								          b .  The  same  applies  to  AST_PBX_KEEPALIVE ,  in  which 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										     case ,  the  chan  ptr  cannot  be  used ,  as  another  thread 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											 owns  it  and  may  have  destroyed  the  channel . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      c .  In  the  former  case ,  you  need  to  check  peer  to  see  if  it  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									         still  exists  before  you  deref  it ,  and  obtain  a  lock . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									      d .  In  neither  case  should  you  do  an  ast_hangup ( peer ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										  e .  Do  not  overwrite  the  result  code  from  ast_bridge_call . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  ! =  AST_PBX_KEEPALIVE  & &  new_chan_cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_channel  * chan_ptr  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-23 16:52:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 		if  ( strcasecmp ( orig_channame ,  chan - > name )  ! =  0 )  {  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 			/* old channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 			chan_ptr  =  ast_get_channel_by_name_locked ( orig_channame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 			if  ( chan_ptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 				if  ( ! ast_bridged_channel ( chan_ptr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 					struct  ast_cdr  * cur ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 					for  ( cur  =  chan_ptr - > cdr ;  cur ;  cur  =  cur - > next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 						if  ( cur  = =  chan_cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 							break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 						} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 					} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 					if  ( cur ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 						ast_cdr_specialized_reset ( chan_cdr , 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 				} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 				ast_channel_unlock ( chan_ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 			} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 			/* new channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 			ast_cdr_specialized_reset ( new_chan_cdr , 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 		}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 			ast_cdr_specialized_reset ( chan_cdr , 0 ) ;  /* nothing changed, reset the chan_cdr  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 		} 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 152535 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r152535 | murf | 2008-10-28 22:36:32 -0600 (Tue, 28 Oct 2008) | 46 lines
The magic trick to avoid this crash is not to
try to find the channel by name in the list,
which is slow and resource consuming, but rather
to pay attention to the result codes from the
ast_bridge_call, to which I added the 
AST_PBX_NO_HANGUP_PEER_PARKED value, which
now are returned when a channel is parked.
Why? because CDR's aren't generated via parking,
so nothing is needed, but if a transfer occurred,
there are critical things I need.
If you get AST_PBX_KEEPALIVE,
then don't touch the channel pointer.
If you get AST_PBX_NO_HANGUP_PEER, or
AST_PBX_NO_HANGUP_PEER_PARKED, then don't
touch the peer pointer.
Updated the several places where the results
from a bridge were not being properly obeyed,
and fixed some code I had introduced so that
the results of the bridge were not overridden 
(in trunk).
All the places that previously tested for 
AST_PBX_NO_HANGUP_PEER now have to check for
both AST_PBX_NO_HANGUP_PEER and AST_PBX_NO_HANGUP_PEER_PARKED.
I tested this against the 4 common parking
scenarios:
1. A calls B; B answers; A parks B; B hangs up while A is getting the parking
slot announcement, immediately after being put on hold.
2. A calls B; B answers; A parks B; B hangs up after A has been hung up, but
before the park times out.
3. A calls B; B answers; B parks A; A hangs up while B is getting the parking slot announcement, immediately after being put on hold.
4. A calls B; B answers; B parks A; A hangs up after B has been hung up, but before the park times out.
No crash.
I also ran the scenarios above against valgrind, and accesses looked good.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@152536 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-10-29 05:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( res  ! =  AST_PBX_NO_HANGUP_PEER_PARKED )  {  /* if the peer was involved in a park, don't even touch it; it's probably gone */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_channel  * chan_ptr  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										new_peer_cdr  =  pick_unlocked_cdr ( peer - > cdr ) ;  /* the proper chan cdr, if there are forked cdrs */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( new_chan_cdr  & &  ast_test_flag ( new_chan_cdr ,  AST_CDR_FLAG_POST_DISABLED )  & &  new_peer_cdr  & &  ! ast_test_flag ( new_peer_cdr ,  AST_CDR_FLAG_POST_DISABLED ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_set_flag ( new_peer_cdr ,  AST_CDR_FLAG_POST_DISABLED ) ;  /* DISABLED is viral-- it will propagate across a bridge */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( strcasecmp ( orig_peername ,  peer - > name )  ! =  0 )  {  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* old channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											chan_ptr  =  ast_get_channel_by_name_locked ( orig_peername ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( chan_ptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! ast_bridged_channel ( chan_ptr ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													struct  ast_cdr  * cur ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													for  ( cur  =  chan_ptr - > cdr ;  cur ;  cur  =  cur - > next )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-23 16:52:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( cur  = =  peer_cdr )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 152535 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r152535 | murf | 2008-10-28 22:36:32 -0600 (Tue, 28 Oct 2008) | 46 lines
The magic trick to avoid this crash is not to
try to find the channel by name in the list,
which is slow and resource consuming, but rather
to pay attention to the result codes from the
ast_bridge_call, to which I added the 
AST_PBX_NO_HANGUP_PEER_PARKED value, which
now are returned when a channel is parked.
Why? because CDR's aren't generated via parking,
so nothing is needed, but if a transfer occurred,
there are critical things I need.
If you get AST_PBX_KEEPALIVE,
then don't touch the channel pointer.
If you get AST_PBX_NO_HANGUP_PEER, or
AST_PBX_NO_HANGUP_PEER_PARKED, then don't
touch the peer pointer.
Updated the several places where the results
from a bridge were not being properly obeyed,
and fixed some code I had introduced so that
the results of the bridge were not overridden 
(in trunk).
All the places that previously tested for 
AST_PBX_NO_HANGUP_PEER now have to check for
both AST_PBX_NO_HANGUP_PEER and AST_PBX_NO_HANGUP_PEER_PARKED.
I tested this against the 4 common parking
scenarios:
1. A calls B; B answers; A parks B; B hangs up while A is getting the parking
slot announcement, immediately after being put on hold.
2. A calls B; B answers; A parks B; B hangs up after A has been hung up, but
before the park times out.
3. A calls B; B answers; B parks A; A hangs up while B is getting the parking slot announcement, immediately after being put on hold.
4. A calls B; B answers; B parks A; A hangs up after B has been hung up, but before the park times out.
No crash.
I also ran the scenarios above against valgrind, and accesses looked good.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@152536 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-10-29 05:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( cur ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_cdr_specialized_reset ( peer_cdr , 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_channel_unlock ( chan_ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* new channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cdr_specialized_reset ( new_peer_cdr , 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cdr_specialized_reset ( peer_cdr , 0 ) ;  /* nothing changed, reset the peer_cdr  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-18 15:01:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief Output parking event to manager */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  post_manager_event ( const  char  * s ,  struct  parkeduser  * pu )  
						 
					
						
							
								
									
										
										
										
											2006-04-21 16:04:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									manager_event ( EVENT_FLAG_CALL ,  s , 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" Exten: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 16:04:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" Channel: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" Parkinglot: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2006-10-02 20:35:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" CallerIDNum: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-22 21:52:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" CallerIDName: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-22 20:02:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										" UniqueID: %s \r \n \r \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-18 15:01:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pu - > parkingexten ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pu - > chan - > name , 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pu - > parkinglot - > name , 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-18 15:01:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										S_OR ( pu - > chan - > cid . cid_num ,  " <unknown> " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-22 20:02:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										S_OR ( pu - > chan - > cid . cid_name ,  " <unknown> " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pu - > chan - > uniqueid 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 16:04:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-10-03 22:40:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief Run management on parkinglots, called once per parkinglot */  
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  manage_parkinglot ( struct  ast_parkinglot  * curlot ,  fd_set  * rfds ,  fd_set  * efds ,  fd_set  * nrfds ,  fd_set  * nefds ,  int  * ms ,  int  * max )  
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-11-01 17:09:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  parkeduser  * pu ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  parkingslot [ AST_MAX_EXTENSION ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 22:39:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Lock parking list */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_LOCK ( & curlot - > parkings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_TRAVERSE_SAFE_BEGIN ( & curlot - > parkings ,  pu ,  list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_channel  * chan  =  pu - > chan ; 	/* shorthand */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  tms ;         /* timeout for this item */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  x ;           /* fd index in channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_context  * con ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( pu - > notquiteyet )  {  /* Pretend this one isn't here yet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										tms  =  ast_tvdiff_ms ( ast_tvnow ( ) ,  pu - > start ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( tms  >  pu - > parkingtime )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Stop music on hold */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_indicate ( pu - > chan ,  AST_CONTROL_UNHOLD ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Get chan, exten from derived kludge */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( pu - > peername [ 0 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												char  * peername  =  ast_strdupa ( pu - > peername ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												char  * cp  =  strrchr ( peername ,  ' - ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-12 17:27:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												char  peername_flat [ AST_MAX_EXTENSION ] ;  /* using something like DAHDI/52 for an extension name is NOT a good idea */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( cp )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													* cp  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_copy_string ( peername_flat , peername , sizeof ( peername_flat ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												for ( i = 0 ;  peername_flat [ i ]  & &  i  <  AST_MAX_EXTENSION ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( peername_flat [ i ]  = =  ' / ' )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														peername_flat [ i ] =  ' 0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												con  =  ast_context_find_or_create ( NULL ,  NULL ,  pu - > parkinglot - > parking_con_dial ,  registrar ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! con )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_ERROR ,  " Parking dial context '%s' does not exist and unable to create \n " ,  pu - > parkinglot - > parking_con_dial ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( con )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													char  returnexten [ AST_MAX_EXTENSION ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													struct  ast_datastore  * features_datastore ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													struct  ast_dial_features  * dialfeatures  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-01 01:30:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-01 01:30:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( ( features_datastore  =  ast_channel_datastore_find ( chan ,  & dial_features_info ,  NULL ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														dialfeatures  =  features_datastore - > data ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-01 01:30:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-01 01:30:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													if  ( dialfeatures ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														snprintf ( returnexten ,  sizeof ( returnexten ) ,  " %s,,%s " ,  peername ,  dialfeatures - > options ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													else  /* Existing default */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														snprintf ( returnexten ,  sizeof ( returnexten ) ,  " %s,,t " ,  peername ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-01 01:30:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_add_extension2 ( con ,  1 ,  peername_flat ,  1 ,  NULL ,  NULL ,  " Dial " ,  ast_strdup ( returnexten ) ,  ast_free_ptr ,  registrar ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( comebacktoorigin )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													set_c_e_p ( chan ,  pu - > parkinglot - > parking_con_dial ,  peername_flat ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 22:39:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " now going to parkedcallstimeout,s,1 | ps is %d \n " , pu - > parkingnum ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													snprintf ( parkingslot ,  sizeof ( parkingslot ) ,  " %d " ,  pu - > parkingnum ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													pbx_builtin_setvar_helper ( chan ,  " PARKINGSLOT " ,  parkingslot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													set_c_e_p ( chan ,  " parkedcallstimeout " ,  peername_flat ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 22:39:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* They've been waiting too long, send them back to where they came.  Theoretically they
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												   should  have  their  original  extensions  and  such ,  but  we  copy  to  be  on  the  safe  side  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												set_c_e_p ( chan ,  pu - > context ,  pu - > exten ,  pu - > priority ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											post_manager_event ( " ParkedCallTimeOut " ,  pu ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_verb ( 2 ,  " Timeout for %s parked on %d (%s). Returning to %s,%s,%d \n " ,  pu - > chan - > name ,  pu - > parkingnum ,  pu - > parkinglot - > name ,  pu - > chan - > context ,  pu - > chan - > exten ,  pu - > chan - > priority ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* Start up the PBX, or hang them up */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_pbx_start ( chan ) )   { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Unable to restart the PBX for user on '%s', hanging them up... \n " ,  pu - > chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											/* And take them out of the parking lot */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											con  =  ast_context_find ( pu - > parkinglot - > parking_con ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( con )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-16 20:43:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ast_context_remove_extension2 ( con ,  pu - > parkingexten ,  1 ,  NULL ,  0 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Whoa, failed to remove the parking extension! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													notify_metermaids ( pu - > parkingexten ,  curlot - > parking_con ,  AST_DEVICE_NOT_INUSE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Whoa, no parking context? \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											AST_LIST_REMOVE_CURRENT ( list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  { 	/* still within parking time, process descriptors */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											for  ( x  =  0 ;  x  <  AST_MAX_FDS ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												struct  ast_frame  * f ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-02-26 07:54:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-29 18:58:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												if  ( ( chan - > fds [ x ]  = =  - 1 )  | |  ( ! FD_ISSET ( chan - > fds [ x ] ,  rfds )  & &  ! FD_ISSET ( pu - > chan - > fds [ x ] ,  efds ) ) )  
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( FD_ISSET ( chan - > fds [ x ] ,  efds ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_set_flag ( chan ,  AST_FLAG_EXCEPTION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_clear_flag ( chan ,  AST_FLAG_EXCEPTION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												chan - > fdno  =  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* See if they need servicing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												f  =  ast_read ( pu - > chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												/* Hangup? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! f  | |  ( ( f - > frametype  = =  AST_FRAME_CONTROL )  & &  ( f - > subclass  = =   AST_CONTROL_HANGUP ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													post_manager_event ( " ParkedCallGiveUp " ,  pu ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-02-26 07:54:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													/* There's a problem, hang them up*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_verb ( 2 ,  " %s got tired of being parked \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 21:41:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													/* And take them out of the parking lot */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													con  =  ast_context_find ( curlot - > parking_con ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( con )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-16 20:43:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
														if  ( ast_context_remove_extension2 ( con ,  pu - > parkingexten ,  1 ,  NULL ,  0 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
															ast_log ( LOG_WARNING ,  " Whoa, failed to remove the extension! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															notify_metermaids ( pu - > parkingexten ,  curlot - > parking_con ,  AST_DEVICE_NOT_INUSE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_log ( LOG_WARNING ,  " Whoa, no parking context for parking lot %s? \n " ,  curlot - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													AST_LIST_REMOVE_CURRENT ( list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													/* XXX Maybe we could do something with packets, like dial "0" for operator or something XXX */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( pu - > moh_trys  <  3  & &  ! chan - > generatordata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_debug ( 1 ,  " MOH on parked call stopped by outside source.  Restarting on channel %s. \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														ast_indicate_data ( chan ,  AST_CONTROL_HOLD ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															S_OR ( curlot - > mohclass ,  NULL ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															( ! ast_strlen_zero ( curlot - > mohclass )  ?  strlen ( curlot - > mohclass )  +  1  :  0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														pu - > moh_trys + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 19:12:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													goto  std ; 	/* XXX Ick: jumping into an else statement??? XXX */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  /* End for */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( x  > =  AST_MAX_FDS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								std : 				for  ( x = 0 ;  x < AST_MAX_FDS ;  x + + )  { 	/* mark fds for next round */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( chan - > fds [ x ]  >  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														FD_SET ( chan - > fds [ x ] ,  nrfds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														FD_SET ( chan - > fds [ x ] ,  nefds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														if  ( chan - > fds [ x ]  >  * max ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
															* max  =  chan - > fds [ x ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												/* Keep track of our shortest wait */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( tms  <  * ms  | |  * ms  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													* ms  =  tms ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_TRAVERSE_SAFE_END ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_UNLOCK ( & curlot - > parkings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Take  care  of  parked  calls  and  unpark  them  if  needed  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  ignore  unused  var . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Start  inf  loop ,  lock  parking  lot ,  check  if  any  parked  channels  have  gone  above  timeout 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  if  so ,  remove  channel  from  parking  lot  and  return  it  to  the  extension  that  parked  it . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Check  if  parked  channel  decided  to  hangup ,  wait  until  next  FD  via  select ( ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  * do_parking_thread ( void  * ignore )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fd_set  rfds ,  efds ; 	/* results from previous select, to be preserved across loops. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fd_set  nrfds ,  nefds ; 	/* args for the next select */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-29 19:10:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									FD_ZERO ( & rfds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FD_ZERO ( & efds ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  ms  =  - 1 ; 	/* select timeout, uninitialized */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  max  =  - 1 ; 	/* max fd, none there yet */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ao2_iterator  iter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_parkinglot  * curlot ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-29 19:10:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										FD_ZERO ( & nrfds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										FD_ZERO ( & nefds ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										iter  =  ao2_iterator_init ( parkinglots ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										while  ( ( curlot  =  ao2_iterator_next ( & iter ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  manage_parkinglot ( curlot ,  & rfds ,  & efds ,  & nrfds ,  & nefds ,  & ms ,  & max ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ao2_ref ( curlot ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										rfds  =  nrfds ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										efds  =  nefds ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 20:32:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											struct  timeval  wait  =  ast_samp2tv ( ms ,  1000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 20:32:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											/* Wait for something to happen */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_select ( max  +  1 ,  & rfds ,  NULL ,  & efds ,  ( ms  >  - 1 )  ?  & wait  :  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 20:32:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										pthread_testcancel ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  NULL ; 	/* Never reached */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief Find parkinglot by name */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  ast_parkinglot  * find_parkinglot ( const  char  * name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_parkinglot  * parkinglot  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_parkinglot  tmp_parkinglot ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_copy_string ( tmp_parkinglot . name ,  name ,  sizeof ( tmp_parkinglot . name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-25 01:01:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									parkinglot  =  ao2_find ( parkinglots ,  & tmp_parkinglot ,  OBJ_POINTER ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( parkinglot  & &  option_debug ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_DEBUG ,  " Found Parkinglot: %s \n " ,  parkinglot - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  parkinglot ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								AST_APP_OPTIONS ( park_call_options ,  BEGIN_OPTIONS  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_APP_OPTION ( ' r ' ,  AST_PARK_OPT_RINGING ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_APP_OPTION ( ' R ' ,  AST_PARK_OPT_RANDOMIZE ) , 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 17:53:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_APP_OPTION ( ' s ' ,  AST_PARK_OPT_SILENCE ) , 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								END_OPTIONS  ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief Park a call */  
						 
					
						
							
								
									
										
										
										
											2004-08-03 06:31:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  park_call_exec ( struct  ast_channel  * chan ,  void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2007-11-21 19:20:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Cache the original channel name in case we get masqueraded in the middle
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  of  a  park - - it  is  still  theoretically  possible  for  a  transfer  to  happen  before 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									 *  we  get  here ,  but  it  is  _really_  unlikely  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * orig_chan_name  =  ast_strdupa ( chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-04 22:57:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  orig_exten [ AST_MAX_EXTENSION ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  orig_priority  =  chan - > priority ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-08-03 06:31:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Data is unused at the moment but could contain a parking
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   lot  context  eventually  */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 02:11:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-24 00:37:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									char  * parse  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_DECLARE_APP_ARGS ( app_args , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( timeout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( return_con ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( return_ext ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( return_pri ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( options ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-26 03:18:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									parse  =  ast_strdupa ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_STANDARD_APP_ARGS ( app_args ,  parse ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-04 22:57:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_copy_string ( orig_exten ,  chan - > exten ,  sizeof ( orig_exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-08-03 06:31:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Setup the exten/priority to be s/1 since we don't know
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									   where  this  call  should  return  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									strcpy ( chan - > exten ,  " s " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									chan - > priority  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Answer if call is not up */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-03 06:31:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( chan - > _state  ! =  AST_STATE_UP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  ast_answer ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Sleep to allow VoIP streams to settle down */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-03 06:31:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  ast_safe_sleep ( chan ,  1000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Park the call */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-04 22:57:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										struct  ast_park_call_args  args  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											. orig_chan_name  =  orig_chan_name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_flags  flags  =  {  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:03:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( parse )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ast_strlen_zero ( app_args . timeout ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( sscanf ( app_args . timeout ,  " %d " ,  & args . timeout )  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Invalid timeout '%s' provided \n " ,  app_args . timeout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													args . timeout  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-06 22:03:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ! ast_strlen_zero ( app_args . return_con ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												args . return_con  =  app_args . return_con ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ast_strlen_zero ( app_args . return_ext ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												args . return_ext  =  app_args . return_ext ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ast_strlen_zero ( app_args . return_pri ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( sscanf ( app_args . return_pri ,  " %d " ,  & args . return_pri )  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													ast_log ( LOG_WARNING ,  " Invalid priority '%s' specified \n " ,  app_args . return_pri ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													args . return_pri  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-29 17:53:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_app_parse_options ( park_call_options ,  & flags ,  NULL ,  app_args . options ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-25 18:18:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										args . flags  =  flags . flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  ast_park_call_full ( chan ,  chan ,  & args ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-04 22:57:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Continue on in the dialplan */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( chan - > exten ,  orig_exten ,  sizeof ( chan - > exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											chan - > priority  =  orig_priority ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											res  =  AST_PBX_KEEPALIVE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 02:11:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-04 22:57:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-03 06:31:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! \brief Pickup parked call */  
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  park_exec_full ( struct  ast_channel  * chan ,  void  * data ,  struct  ast_parkinglot  * parkinglot )  
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2006-08-21 02:11:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * peer = NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-09 02:29:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  parkeduser  * pu ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-03 06:31:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_context  * con ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 20:30:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  park  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_bridge_config  config ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 20:56:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( data ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 20:30:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										park  =  atoi ( ( char  * ) data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-09 02:29:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									parkinglot  =  find_parkinglot ( findparkinglotname ( chan ) ) ;  	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! parkinglot ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										parkinglot  =  default_parkinglot ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_LOCK ( & parkinglot - > parkings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_LIST_TRAVERSE_SAFE_BEGIN ( & parkinglot - > parkings ,  pu ,  list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-13 20:30:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! data  | |  pu - > parkingnum  = =  park )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-09 19:27:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( pu - > chan - > pbx )  {  /* do not allow call to be picked up until the PBX thread is finished */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												AST_LIST_UNLOCK ( & parkinglot - > parkings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-08 05:28:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AST_LIST_REMOVE_CURRENT ( list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-09 02:29:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_LIST_TRAVERSE_SAFE_END 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_LIST_UNLOCK ( & parkinglot - > parkings ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-09 02:29:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( pu )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										peer  =  pu - > chan ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										con  =  ast_context_find ( parkinglot - > parking_con ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-03 06:31:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( con )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-16 20:43:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ast_context_remove_extension2 ( con ,  pu - > parkingexten ,  1 ,  NULL ,  0 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-03 06:31:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Whoa, failed to remove the extension! \n " ) ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												notify_metermaids ( pu - > parkingexten ,  parkinglot - > parking_con ,  AST_DEVICE_NOT_INUSE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-03 06:31:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Whoa, no parking context? \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-02-26 07:54:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										manager_event ( EVENT_FLAG_CALL ,  " UnParkedCall " , 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											" Exten: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2005-02-26 07:54:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											" Channel: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" From: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2006-10-02 20:35:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											" CallerIDNum: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 10:47:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											" CallerIDName: %s \r \n " , 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											pu - > parkingexten ,  pu - > chan - > name ,  chan - > name , 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 10:47:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											S_OR ( pu - > chan - > cid . cid_num ,  " <unknown> " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											S_OR ( pu - > chan - > cid . cid_name ,  " <unknown> " ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-02-26 07:54:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_free ( pu ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-02 19:37:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* JK02: it helps to answer the channel if not already up */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 20:32:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( chan - > _state  ! =  AST_STATE_UP ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-02 19:37:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_answer ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									//XXX Why do we unlock here ?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// uncomment it for now, till my setup with debug_threads and detect_deadlocks starts to complain
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//ASTOBJ_UNLOCK(parkinglot);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  ( peer )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-08 00:25:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Play a courtesy to the source(s) configured to prefix the bridge connecting */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										
							 
						 
					
						
							
								
									
										
										
										
											2004-08-31 13:32:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ast_strlen_zero ( courtesytone ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 20:32:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											int  error  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_indicate ( peer ,  AST_CONTROL_UNHOLD ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-08 00:25:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( parkedplay  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-17 23:18:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												error  =  ast_stream_and_wait ( chan ,  courtesytone ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 21:41:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( parkedplay  = =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-17 23:18:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												error  =  ast_stream_and_wait ( peer ,  courtesytone ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 20:32:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( parkedplay  = =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												if  ( ! ast_streamfile ( chan ,  courtesytone ,  chan - > language )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														! ast_streamfile ( peer ,  courtesytone ,  chan - > language ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-17 04:31:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													/*! \todo XXX we would like to wait on both! */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 20:32:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
													res  =  ast_waitstream ( chan ,  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( res  > =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														res  =  ast_waitstream ( peer ,  " " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													if  ( res  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
														error  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-31 13:32:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-04 23:04:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 20:32:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Failed to play courtesy tone! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_hangup ( peer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-31 13:32:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-19 20:44:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-03 21:39:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_indicate ( peer ,  AST_CONTROL_UNHOLD ) ;  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										res  =  ast_channel_make_compatible ( chan ,  peer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Could not make channels %s and %s compatible for bridge \n " ,  chan - > name ,  peer - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( peer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* This runs sorta backwards, since we give the incoming channel control, as if it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   were  the  person  called .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_verb ( 3 ,  " Channel %s connected to parked call %d \n " ,  chan - > name ,  park ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-30 14:37:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  " PARKEDCHANNEL " ,  peer - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cdr_setdestchan ( chan - > cdr ,  peer - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										memset ( & config ,  0 ,  sizeof ( struct  ast_bridge_config ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( parkinglot - > parkedcalltransfers  = =  AST_FEATURE_FLAG_BYCALLEE )  | |  ( parkinglot - > parkedcalltransfers  = =  AST_FEATURE_FLAG_BYBOTH ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-16 17:50:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_set_flag ( & ( config . features_callee ) ,  AST_FEATURE_REDIRECT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( parkinglot - > parkedcalltransfers  = =  AST_FEATURE_FLAG_BYCALLER )  | |  ( parkinglot - > parkedcalltransfers  = =  AST_FEATURE_FLAG_BYBOTH ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-16 17:50:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_set_flag ( & ( config . features_caller ) ,  AST_FEATURE_REDIRECT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( parkinglot - > parkedcallreparking  = =  AST_FEATURE_FLAG_BYCALLEE )  | |  ( parkinglot - > parkedcallreparking  = =  AST_FEATURE_FLAG_BYBOTH ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-16 17:41:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_set_flag ( & ( config . features_callee ) ,  AST_FEATURE_PARKCALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( parkinglot - > parkedcallreparking  = =  AST_FEATURE_FLAG_BYCALLER )  | |  ( parkinglot - > parkedcallreparking  = =  AST_FEATURE_FLAG_BYBOTH ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-16 17:41:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_set_flag ( & ( config . features_caller ) ,  AST_FEATURE_PARKCALL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										res  =  ast_bridge_call ( chan ,  peer ,  & config ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-01-23 20:36:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  " PARKEDCHANNEL " ,  peer - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cdr_setdestchan ( chan - > cdr ,  peer - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										/* Simulate the PBX hanging up */ 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merged revisions 152535 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r152535 | murf | 2008-10-28 22:36:32 -0600 (Tue, 28 Oct 2008) | 46 lines
The magic trick to avoid this crash is not to
try to find the channel by name in the list,
which is slow and resource consuming, but rather
to pay attention to the result codes from the
ast_bridge_call, to which I added the 
AST_PBX_NO_HANGUP_PEER_PARKED value, which
now are returned when a channel is parked.
Why? because CDR's aren't generated via parking,
so nothing is needed, but if a transfer occurred,
there are critical things I need.
If you get AST_PBX_KEEPALIVE,
then don't touch the channel pointer.
If you get AST_PBX_NO_HANGUP_PEER, or
AST_PBX_NO_HANGUP_PEER_PARKED, then don't
touch the peer pointer.
Updated the several places where the results
from a bridge were not being properly obeyed,
and fixed some code I had introduced so that
the results of the bridge were not overridden 
(in trunk).
All the places that previously tested for 
AST_PBX_NO_HANGUP_PEER now have to check for
both AST_PBX_NO_HANGUP_PEER and AST_PBX_NO_HANGUP_PEER_PARKED.
I tested this against the 4 common parking
scenarios:
1. A calls B; B answers; A parks B; B hangs up while A is getting the parking
slot announcement, immediately after being put on hold.
2. A calls B; B answers; A parks B; B hangs up after A has been hung up, but
before the park times out.
3. A calls B; B answers; B parks A; A hangs up while B is getting the parking slot announcement, immediately after being put on hold.
4. A calls B; B answers; B parks A; A hangs up after B has been hung up, but before the park times out.
No crash.
I also ran the scenarios above against valgrind, and accesses looked good.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@152536 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-10-29 05:01:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( res  ! =  AST_PBX_NO_HANGUP_PEER  & &  res  ! =  AST_PBX_NO_HANGUP_PEER_PARKED ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											ast_hangup ( peer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-07 04:11:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-17 04:31:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/*! \todo XXX Play a message XXX */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-17 23:18:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ast_stream_and_wait ( chan ,  " pbx-invalidpark " ,  " " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-28 23:49:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " ast_streamfile of %s failed on %s \n " ,  " pbx-invalidpark " ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_verb ( 3 ,  " Channel %s tried to talk to nonexistent parked call %d \n " ,  chan - > name ,  park ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 02:11:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  park_exec ( struct  ast_channel  * chan ,  void  * data )   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  park_exec_full ( chan ,  data ,  default_parkinglot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Unreference parkinglot object. If no more references,
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									then  go  ahead  and  delete  it  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  parkinglot_unref ( struct  ast_parkinglot  * parkinglot )   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  refcount  =  ao2_ref ( parkinglot ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( option_debug  >  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_DEBUG ,  " Multiparking: %s refcount now %d \n " ,  parkinglot - > name ,  refcount  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_parkinglot  * parkinglot_addref ( struct  ast_parkinglot  * parkinglot )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  refcount  =  ao2_ref ( parkinglot ,  + 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( option_debug  >  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_DEBUG ,  " Multiparking: %s refcount now %d \n " ,  parkinglot - > name ,  refcount  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  parkinglot ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Allocate parking lot structure */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_parkinglot  * create_parkinglot ( char  * name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_parkinglot  * newlot  =  ( struct  ast_parkinglot  * )  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									newlot  =  ao2_alloc ( sizeof ( * newlot ) ,  parkinglot_destroy ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! newlot ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_copy_string ( newlot - > name ,  name ,  sizeof ( newlot - > name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  newlot ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Destroy a parking lot */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  void  parkinglot_destroy ( void  * obj )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_parkinglot  * ruin  =  obj ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_context  * con ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									con  =  ast_context_find ( ruin - > parking_con ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( con ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_context_destroy ( con ,  registrar ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_unlink ( parkinglots ,  ruin ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*! \brief Build parkinglot from configuration and chain it in */  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  struct  ast_parkinglot  * build_parkinglot ( char  * name ,  struct  ast_variable  * var )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_parkinglot  * parkinglot ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_context  * con  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_variable  * confvar  =  var ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  error  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  start  =  0 ,  end  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  oldparkinglot  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parkinglot  =  find_parkinglot ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( parkinglot ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										oldparkinglot  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										parkinglot  =  create_parkinglot ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! parkinglot ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_lock ( parkinglot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( option_debug ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_DEBUG ,  " Building parking lot %s \n " ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Do some config stuff */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while ( confvar )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( confvar - > name ,  " context " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( parkinglot - > parking_con ,  confvar - > value ,  sizeof ( parkinglot - > parking_con ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( confvar - > name ,  " parkingtime " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( sscanf ( confvar - > value ,  " %d " ,  & parkinglot - > parkingtime )  ! =  1 )  | |  ( parkinglot - > parkingtime  <  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " %s is not a valid parkingtime \n " ,  confvar - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												parkinglot - > parkingtime  =  DEFAULT_PARK_TIME ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												parkinglot - > parkingtime  =  parkinglot - > parkingtime  *  1000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( confvar - > name ,  " parkpos " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( sscanf ( confvar - > value ,  " %d-%d " ,  & start ,  & end )  ! =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Format for parking positions is a-b, where a and b are numbers at line %d of parking.conf \n " ,  confvar - > lineno ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												error  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												parkinglot - > parking_start  =  start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												parkinglot - > parking_stop  =  end ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( confvar - > name ,  " findslot " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											parkinglot - > parkfindnext  =  ( ! strcasecmp ( confvar - > value ,  " next " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										confvar  =  confvar - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* make sure parkingtime is set if not specified */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( parkinglot - > parkingtime  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										parkinglot - > parkingtime  =  DEFAULT_PARK_TIME ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! var )  { 	/* Default parking lot */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( parkinglot - > parking_con ,  " parkedcalls " ,  sizeof ( parkinglot - > parking_con ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( parkinglot - > parking_con_dial ,  " park-dial " ,  sizeof ( parkinglot - > parking_con_dial ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( parkinglot - > mohclass ,  " default " ,  sizeof ( parkinglot - > mohclass ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Check for errors */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( parkinglot - > parking_con ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Parking lot %s lacks context \n " ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										error  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Create context */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! error  & &  ! ( con  =  ast_context_find_or_create ( NULL ,  NULL ,  parkinglot - > parking_con ,  registrar ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Parking context '%s' does not exist and unable to create \n " ,  parkinglot - > parking_con ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										error  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Add a parking extension into the context */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! oldparkinglot )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												(closes issue #13202)
Reported by: falves11
Tested by: murf
falves11 ==
The changes I introduce here seem to clear up the problem
for me. However, if they do not for you, please reopen this
bug, and we'll keep digging.
The root of this problem seems to be a subtle memory corruption
introduced when creating an extension with an empty extension
name. While valgrind cannot detect it outside of DEBUG_MALLOC
mode, when compiled with DEBUG_MALLOC, this is certain death.
The code in main/features.c is a puzzle to me. On the initial
module load, the code is attempting to add the parking extension
before the features.conf file has even been opened!
I just wrapped the offending call with an if() that will not
try to add the extension if the extension name is empty. THis
seems to solve the corruption, and let the "memory show allocations"
work as one would expect.
But, really, adding an extension with an empty name is a seriously
bad thing to allow, as it will mess up all the pattern matching 
algorithms, etc. So, I added a statement to the add_extension2 code to return
a -1 if this is attempted.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@135265 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-08-02 04:51:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ! ast_strlen_zero ( ast_parking_ext ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_add_extension2 ( con ,  1 ,  ast_parking_ext ( ) ,  1 ,  NULL ,  NULL ,  parkcall ,  strdup ( " " ) ,  ast_free ,  registrar )  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												error  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ao2_unlock ( parkinglot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( error )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Parking %s not open for business. Configuration error. \n " ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										parkinglot_destroy ( parkinglot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( option_debug ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_DEBUG ,  " Parking %s now open for business. (start exten %d end %d) \n " ,  name ,  start ,  end ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Move it into the list, if it wasn't already there */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! oldparkinglot )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_link ( parkinglots ,  parkinglot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									parkinglot_unref ( parkinglot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  parkinglot ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Add  parking  hints  for  all  defined  parking  lots  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  context 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  start  starting  parkinglot  number 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  stop  ending  parkinglot  number 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  park_add_hints ( char  * context ,  int  start ,  int  stop )  
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  numext ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  device [ AST_MAX_EXTENSION ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  exten [ 10 ] ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( numext  =  start ;  numext  < =  stop ;  numext + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										snprintf ( exten ,  sizeof ( exten ) ,  " %d " ,  numext ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										snprintf ( device ,  sizeof ( device ) ,  " park:%s@%s " ,  exten ,  context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_add_extension ( context ,  1 ,  exten ,  PRIORITY_HINT ,  NULL ,  NULL ,  device ,  NULL ,  NULL ,  registrar ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  load_config ( void )   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  start  =  0 ,  end  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_context  * con  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_config  * cfg  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_variable  * var  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  feature_group  * fg  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_flags  config_flags  =  {  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  old_parking_ext [ AST_MAX_EXTENSION ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  old_parking_con [ AST_MAX_EXTENSION ]  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * ctg ;  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									static  const  char  * categories [ ]  =  {  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Categories in features.conf that are not
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  to  be  parsed  as  group  categories 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" general " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" featuremap " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" applicationmap " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( default_parkinglot )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										strcpy ( old_parking_con ,  default_parkinglot - > parking_con ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										strcpy ( old_parking_ext ,  parking_ext ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										default_parkinglot  =  build_parkinglot ( DEFAULT_PARKINGLOT ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( default_parkinglot )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ao2_lock ( default_parkinglot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default_parkinglot - > parking_start  =  701 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default_parkinglot - > parking_stop  =  750 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default_parkinglot - > parking_offset  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											default_parkinglot - > parkfindnext  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-11 21:38:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											default_parkinglot - > parkingtime  =  DEFAULT_PARK_TIME ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ao2_unlock ( default_parkinglot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( default_parkinglot )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( option_debug ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_DEBUG ,  " Configuration of default parkinglot done. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Configuration of default parkinglot failed. \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Reset to defaults */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									strcpy ( parking_ext ,  " 700 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									strcpy ( pickup_ext ,  " *8 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									courtesytone [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									strcpy ( xfersound ,  " beep " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									strcpy ( xferfailsound ,  " pbx-invalid " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									adsipark  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									comebacktoorigin  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default_parkinglot - > parkaddhints  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default_parkinglot - > parkedcalltransfers  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									default_parkinglot - > parkedcallreparking  =  0 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									transferdigittimeout  =  DEFAULT_TRANSFER_DIGIT_TIMEOUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									featuredigittimeout  =  DEFAULT_FEATURE_DIGIT_TIMEOUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									atxfernoanswertimeout  =  DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									atxferloopdelay  =  DEFAULT_ATXFER_LOOP_DELAY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									atxferdropcall  =  DEFAULT_ATXFER_DROP_CALL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									atxfercallbackretries  =  DEFAULT_ATXFER_CALLBACK_RETRIES ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-03-26 18:39:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									cfg  =  ast_config_load2 ( " features.conf " ,  " features " ,  config_flags ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-12 23:30:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( cfg  = =  CONFIG_STATUS_FILEMISSING  | |  cfg  = =  CONFIG_STATUS_FILEUNCHANGED  | |  cfg  = =  CONFIG_STATUS_FILEINVALID )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING , " Could not load features.conf \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									for  ( var  =  ast_variable_browse ( cfg ,  " general " ) ;  var ;  var  =  var - > next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( var - > name ,  " parkext " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( parking_ext ,  var - > value ,  sizeof ( parking_ext ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " context " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_copy_string ( default_parkinglot - > parking_con ,  var - > value ,  sizeof ( default_parkinglot - > parking_con ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " parkingtime " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											if  ( ( sscanf ( var - > value ,  " %d " ,  & default_parkinglot - > parkingtime )  ! =  1 )  | |  ( default_parkinglot - > parkingtime  <  1 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " %s is not a valid parkingtime \n " ,  var - > value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												default_parkinglot - > parkingtime  =  DEFAULT_PARK_TIME ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												default_parkinglot - > parkingtime  =  default_parkinglot - > parkingtime  *  1000 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " parkpos " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( sscanf ( var - > value ,  " %d-%d " ,  & start ,  & end )  ! =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Format for parking positions is a-b, where a and b are numbers at line %d of features.conf \n " ,  var - > lineno ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  if  ( default_parkinglot )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												default_parkinglot - > parking_start  =  start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												default_parkinglot - > parking_stop  =  end ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " No default parking lot! \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " findslot " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											default_parkinglot - > parkfindnext  =  ( ! strcasecmp ( var - > value ,  " next " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " parkinghints " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											default_parkinglot - > parkaddhints  =  ast_true ( var - > value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " parkedcalltransfers " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! strcasecmp ( var - > value ,  " both " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												default_parkinglot - > parkedcalltransfers  =  AST_FEATURE_FLAG_BYBOTH ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											else  if  ( ! strcasecmp ( var - > value ,  " caller " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												default_parkinglot - > parkedcalltransfers  =  AST_FEATURE_FLAG_BYCALLER ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											else  if  ( ! strcasecmp ( var - > value ,  " callee " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												default_parkinglot - > parkedcalltransfers  =  AST_FEATURE_FLAG_BYCALLEE ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " parkedcallreparking " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! strcasecmp ( var - > value ,  " both " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												default_parkinglot - > parkedcallreparking  =  AST_FEATURE_FLAG_BYBOTH ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											else  if  ( ! strcasecmp ( var - > value ,  " caller " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												default_parkinglot - > parkedcallreparking  =  AST_FEATURE_FLAG_BYCALLER ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											else  if  ( ! strcasecmp ( var - > value ,  " callee " ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												default_parkinglot - > parkedcallreparking  =  AST_FEATURE_FLAG_BYCALLEE ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " adsipark " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											adsipark  =  ast_true ( var - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " transferdigittimeout " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( sscanf ( var - > value ,  " %d " ,  & transferdigittimeout )  ! =  1 )  | |  ( transferdigittimeout  <  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " %s is not a valid transferdigittimeout \n " ,  var - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												transferdigittimeout  =  DEFAULT_TRANSFER_DIGIT_TIMEOUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												transferdigittimeout  =  transferdigittimeout  *  1000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " featuredigittimeout " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( sscanf ( var - > value ,  " %d " ,  & featuredigittimeout )  ! =  1 )  | |  ( featuredigittimeout  <  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " %s is not a valid featuredigittimeout \n " ,  var - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												featuredigittimeout  =  DEFAULT_FEATURE_DIGIT_TIMEOUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " atxfernoanswertimeout " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( sscanf ( var - > value ,  " %d " ,  & atxfernoanswertimeout )  ! =  1 )  | |  ( atxfernoanswertimeout  <  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " %s is not a valid atxfernoanswertimeout \n " ,  var - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												atxfernoanswertimeout  =  DEFAULT_NOANSWER_TIMEOUT_ATTENDED_TRANSFER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												atxfernoanswertimeout  =  atxfernoanswertimeout  *  1000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " atxferloopdelay " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( sscanf ( var - > value ,  " %u " ,  & atxferloopdelay )  ! =  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " %s is not a valid atxferloopdelay \n " ,  var - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												atxferloopdelay  =  DEFAULT_ATXFER_LOOP_DELAY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											}  else  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												atxferloopdelay  * =  1000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " atxferdropcall " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											atxferdropcall  =  ast_true ( var - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " atxfercallbackretries " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ( sscanf ( var - > value ,  " %u " ,  & atxferloopdelay )  ! =  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " %s is not a valid atxfercallbackretries \n " ,  var - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												atxfercallbackretries  =  DEFAULT_ATXFER_CALLBACK_RETRIES ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " courtesytone " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( courtesytone ,  var - > value ,  sizeof ( courtesytone ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}   else  if  ( ! strcasecmp ( var - > name ,  " parkedplay " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! strcasecmp ( var - > value ,  " both " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												parkedplay  =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else  if  ( ! strcasecmp ( var - > value ,  " parked " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												parkedplay  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												parkedplay  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " xfersound " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( xfersound ,  var - > value ,  sizeof ( xfersound ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " xferfailsound " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( xferfailsound ,  var - > value ,  sizeof ( xferfailsound ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " pickupexten " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( pickup_ext ,  var - > value ,  sizeof ( pickup_ext ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " comebacktoorigin " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											comebacktoorigin  =  ast_true ( var - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										}  else  if  ( ! strcasecmp ( var - > name ,  " parkedmusicclass " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_copy_string ( default_parkinglot - > mohclass ,  var - > value ,  sizeof ( default_parkinglot - > mohclass ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									unmap_features ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( var  =  ast_variable_browse ( cfg ,  " featuremap " ) ;  var ;  var  =  var - > next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( remap_feature ( var - > name ,  var - > value ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_NOTICE ,  " Unknown feature '%s' \n " ,  var - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Map a key combination to an application*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_unregister_features ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( var  =  ast_variable_browse ( cfg ,  " applicationmap " ) ;  var ;  var  =  var - > next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  * tmp_val  =  ast_strdupa ( var - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										char  * exten ,  * activateon ,  * activatedby ,  * app ,  * app_args ,  * moh_class ;  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										struct  ast_call_feature  * feature ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* strsep() sets the argument to NULL if match not found, and it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  is  safe  to  use  it  with  a  NULL  argument ,  so  we  don ' t  check 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 *  between  calls . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										exten  =  strsep ( & tmp_val , " , " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										activatedby  =  strsep ( & tmp_val , " , " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										app  =  strsep ( & tmp_val , " , " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										app_args  =  strsep ( & tmp_val , " , " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										moh_class  =  strsep ( & tmp_val , " , " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										activateon  =  strsep ( & activatedby ,  " / " ) ; 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/*! \todo XXX var_name or app_args ? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_strlen_zero ( app )  | |  ast_strlen_zero ( exten )  | |  ast_strlen_zero ( activateon )  | |  ast_strlen_zero ( var - > name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_NOTICE ,  " Please check the feature Mapping Syntax, either extension, name, or app aren't provided %s %s %s %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												app ,  exten ,  activateon ,  var - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										AST_RWLIST_RDLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  ( ( feature  =  find_dynamic_feature ( var - > name ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AST_RWLIST_UNLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Dynamic Feature '%s' specified more than once! \n " ,  var - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										AST_RWLIST_UNLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( feature  =  ast_calloc ( 1 ,  sizeof ( * feature ) ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 					
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( feature - > sname ,  var - > name ,  FEATURE_SNAME_LEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( feature - > app ,  app ,  FEATURE_APP_LEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( feature - > exten ,  exten ,  FEATURE_EXTEN_LEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( app_args )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( feature - > app_args ,  app_args ,  FEATURE_APP_ARGS_LEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( moh_class ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_copy_string ( feature - > moh_class ,  moh_class ,  FEATURE_MOH_LEN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_copy_string ( feature - > exten ,  exten ,  sizeof ( feature - > exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										feature - > operation  =  feature_exec_app ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_set_flag ( feature ,  AST_FEATURE_FLAG_NEEDSDTMF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Allow caller and calle to be specified for backwards compatability */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strcasecmp ( activateon ,  " self " )  | |  ! strcasecmp ( activateon ,  " caller " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_set_flag ( feature ,  AST_FEATURE_FLAG_ONSELF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else  if  ( ! strcasecmp ( activateon ,  " peer " )  | |  ! strcasecmp ( activateon ,  " callee " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_set_flag ( feature ,  AST_FEATURE_FLAG_ONPEER ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_NOTICE ,  " Invalid 'ActivateOn' specification for feature '%s', " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"  must be 'self', or 'peer' \n " ,  var - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_strlen_zero ( activatedby ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_set_flag ( feature ,  AST_FEATURE_FLAG_BYBOTH ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else  if  ( ! strcasecmp ( activatedby ,  " caller " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_set_flag ( feature ,  AST_FEATURE_FLAG_BYCALLER ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else  if  ( ! strcasecmp ( activatedby ,  " callee " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_set_flag ( feature ,  AST_FEATURE_FLAG_BYCALLEE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else  if  ( ! strcasecmp ( activatedby ,  " both " ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_set_flag ( feature ,  AST_FEATURE_FLAG_BYBOTH ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_NOTICE ,  " Invalid 'ActivatedBy' specification for feature '%s', " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												"  must be 'caller', or 'callee', or 'both' \n " ,  var - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_register_feature ( feature ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_verb ( 2 ,  " Mapping Feature '%s' to app '%s(%s)' with code '%s' \n " ,  var - > name ,  app ,  app_args ,  exten ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_unregister_groups ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_WRLOCK ( & feature_groups ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ctg  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( ctg  =  ast_category_browse ( cfg ,  ctg ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										/* Is this a parkinglot definition ? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! strncasecmp ( ctg ,  " parkinglot_ " ,  strlen ( " parkinglot_ " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 2 ,  " Found configuration section %s, assume parking context \n " ,  ctg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if ( ! build_parkinglot ( ctg ,  ast_variable_browse ( cfg ,  ctg ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_ERROR ,  " Could not build parking lot %s. Configuration error. \n " ,  ctg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_debug ( 1 ,  " Configured parking context %s \n " ,  ctg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* No, check if it's a group */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										for  ( i  =  0 ;  i  <  ARRAY_LEN ( categories ) ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! strcasecmp ( categories [ i ] ,  ctg ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( i  <  ARRAY_LEN ( categories ) )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ( fg  =  register_group ( ctg ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										for  ( var  =  ast_variable_browse ( cfg ,  ctg ) ;  var ;  var  =  var - > next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											struct  ast_call_feature  * feature ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AST_RWLIST_RDLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ! ( feature  =  find_dynamic_feature ( var - > name ) )  & &  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											    ! ( feature  =  ast_find_call_feature ( var - > name ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												AST_RWLIST_UNLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Feature '%s' was not found. \n " ,  var - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											AST_RWLIST_UNLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											register_group_feature ( fg ,  var - > value ,  feature ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_RWLIST_UNLOCK ( & feature_groups ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_config_destroy ( cfg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Remove the old parking extension */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ast_strlen_zero ( old_parking_con )  & &  ( con  =  ast_context_find ( old_parking_con ) ) ) 	{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-16 20:43:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if ( ast_context_remove_extension2 ( con ,  old_parking_ext ,  1 ,  registrar ,  0 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												notify_metermaids ( old_parking_ext ,  old_parking_con ,  AST_DEVICE_NOT_INUSE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Removed old parking extension %s@%s \n " ,  old_parking_ext ,  old_parking_con ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( con  =  ast_context_find_or_create ( NULL ,  NULL ,  default_parkinglot - > parking_con ,  registrar ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_ERROR ,  " Parking context '%s' does not exist and unable to create \n " ,  default_parkinglot - > parking_con ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  ast_add_extension2 ( con ,  1 ,  ast_parking_ext ( ) ,  1 ,  NULL ,  NULL ,  parkcall ,  NULL ,  NULL ,  registrar ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( default_parkinglot - > parkaddhints ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										park_add_hints ( default_parkinglot - > parking_con ,  default_parkinglot - > parking_start ,  default_parkinglot - > parking_stop ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! res ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										notify_metermaids ( ast_parking_ext ( ) ,  default_parkinglot - > parking_con ,  AST_DEVICE_INUSE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ brief  CLI  command  to  list  configured  features 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  e 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  cmd 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  a 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ retval  CLI_SUCCESS  on  success . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  NULL  when  tab  completion  is  used . 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  char  * handle_feature_show ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
									
										
										
										
											2003-07-02 14:06:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_call_feature  * feature ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ao2_iterator  iter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_parkinglot  * curlot ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-18 15:43:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# define HFS_FORMAT "%-25s %-7s %-7s\n" 
  
						 
					
						
							
								
									
										
										
										
											2003-07-02 14:06:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 14:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 14:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										e - > command  =  " features show " ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 14:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											" Usage: features show \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        Lists configured features \n " ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 14:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-04 23:04:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 14:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-03-18 15:43:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  HFS_FORMAT ,  " Builtin Feature " ,  " Default " ,  " Current " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  HFS_FORMAT ,  " --------------- " ,  " ------- " ,  " ------- " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 14:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-03-18 15:43:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  HFS_FORMAT ,  " Pickup " ,  " *8 " ,  ast_pickup_ext ( ) ) ;           /* default hardcoded above, so we'll hardcode it here */ 
							 
						 
					
						
							
								
									
										
										
										
											2003-07-02 14:06:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_rwlock_rdlock ( & features_lock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ( i  =  0 ;  i  <  FEATURES_COUNT ;  i + + ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-18 15:43:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  HFS_FORMAT ,  builtin_features [ i ] . fname ,  builtin_features [ i ] . default_exten ,  builtin_features [ i ] . exten ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_rwlock_unlock ( & features_lock ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-07-02 14:06:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  " \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-18 15:43:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  HFS_FORMAT ,  " Dynamic Feature " ,  " Default " ,  " Current " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  HFS_FORMAT ,  " --------------- " ,  " ------- " ,  " ------- " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( AST_RWLIST_EMPTY ( & feature_list ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " (none) \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_RWLIST_RDLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_RWLIST_TRAVERSE ( & feature_list ,  feature ,  feature_entry )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-18 15:43:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											ast_cli ( a - > fd ,  HFS_FORMAT ,  feature - > sname ,  " no def " ,  feature - > exten ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-11 17:06:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_RWLIST_UNLOCK ( & feature_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-07-02 14:06:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// loop through all the parking lots
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									iter  =  ao2_iterator_init ( parkinglots ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( curlot  =  ao2_iterator_next ( & iter ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " \n Call parking (Parking lot: %s) \n " ,  curlot - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " ------------ \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd , " %-22s:      %s \n " ,  " Parking extension " ,  parking_ext ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd , " %-22s:      %s \n " ,  " Parking context " ,  curlot - > parking_con ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd , " %-22s:      %d-%d \n " ,  " Parked call extensions " ,  curlot - > parking_start ,  curlot - > parking_stop ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd , " \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_ref ( curlot ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-07-02 14:06:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 14:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  ast_features_reload ( void )  
						 
					
						
							
								
									
										
										
										
											2007-06-06 14:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Release parking lot list */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//ASTOBJ_CONTAINER_MARKALL(&parkinglots);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// TODO: I don't think any marking is necessary
 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Reload configuration */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  load_config ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									//ASTOBJ_CONTAINER_PRUNE_MARKED(&parkinglots, parkinglot_destroy);
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-07-02 14:06:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * handle_features_reload ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  ( cmd )  { 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " features reload " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: features reload \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        Reloads configured call features from features.conf \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-04 23:04:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_features_reload ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-07-02 14:06:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2005-07-25 17:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  mandescr_bridge [ ]  =  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								" Description: Bridge together two channels already in the PBX \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								" Variables: ( Headers marked with * are required ) \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								"    *Channel1: Channel to Bridge to Channel2 \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								"    *Channel2: Channel to Bridge to Channel1 \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								"         Tone: (Yes|No) Play courtesy tone to Channel 2 \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								" \n " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Actual  bridge 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  chan 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  tmpchan 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Stop  hold  music ,  lock  both  channels ,  masq  channels , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  after  bridge  return  channel  to  next  priority . 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  void  do_bridge_masquerade ( struct  ast_channel  * chan ,  struct  ast_channel  * tmpchan )  
						 
					
						
							
								
									
										
										
										
											2004-01-30 05:49:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_moh_stop ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_setstate ( tmpchan ,  chan - > _state ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tmpchan - > readformat  =  chan - > readformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tmpchan - > writeformat  =  chan - > writeformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_masquerade ( tmpchan ,  chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_lock ( tmpchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_do_masquerade ( tmpchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* when returning from bridge, the channel will continue at the next priority */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_explicit_goto ( tmpchan ,  chan - > context ,  chan - > exten ,  chan - > priority  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unlock ( tmpchan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-01-30 05:49:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ brief  Bridge  channels  together 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  m 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Make  sure  valid  channels  were  specified ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  send  errors  if  any  of  the  channels  could  not  be  found / locked ,  answer  channels  if  needed , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  create  the  placeholder  channels  and  grab  the  other  channels  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  make  the  channels  compatible ,  send  error  if  we  fail  doing  so  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  setup  the  bridge  thread  object  and  start  the  bridge . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  0  on  success  or  on  incorrect  use . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  1  on  failure  to  bridge  channels . 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  action_bridge ( struct  mansession  * s ,  const  struct  message  * m )  
						 
					
						
							
								
									
										
										
										
											2006-03-06 23:12:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									const  char  * channela  =  astman_get_header ( m ,  " Channel1 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * channelb  =  astman_get_header ( m ,  " Channel2 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * playtone  =  astman_get_header ( m ,  " Tone " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chana  =  NULL ,  * chanb  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * tmpchana  =  NULL ,  * tmpchanb  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_bridge_thread_obj  * tobj  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-06 23:12:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* make sure valid channels were specified */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ast_strlen_zero ( channela )  & &  ! ast_strlen_zero ( channelb ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										chana  =  ast_get_channel_by_name_prefix_locked ( channela ,  strlen ( channela ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										chanb  =  ast_get_channel_by_name_prefix_locked ( channelb ,  strlen ( channelb ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( chana ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_channel_unlock ( chana ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( chanb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_channel_unlock ( chanb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* send errors if any of the channels could not be found/locked */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! chana )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											char  buf [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											snprintf ( buf ,  sizeof ( buf ) ,  " Channel1 does not exists: %s " ,  channela ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											astman_send_error ( s ,  m ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! chanb )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											char  buf [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											snprintf ( buf ,  sizeof ( buf ) ,  " Channel2 does not exists: %s " ,  channelb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											astman_send_error ( s ,  m ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										astman_send_error ( s ,  m ,  " Missing channel parameter in request " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-06 23:12:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* Answer the channels if needed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( chana - > _state  ! =  AST_STATE_UP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_answer ( chana ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( chanb - > _state  ! =  AST_STATE_UP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_answer ( chanb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* create the placeholder channels and grab the other channels */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( tmpchana  =  ast_channel_alloc ( 0 ,  AST_STATE_DOWN ,  NULL ,  NULL ,  NULL ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										NULL ,  NULL ,  0 ,  " Bridge/%s " ,  chana - > name ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										astman_send_error ( s ,  m ,  " Unable to create temporary channel! " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-06 23:12:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ( tmpchanb  =  ast_channel_alloc ( 0 ,  AST_STATE_DOWN ,  NULL ,  NULL ,  NULL ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										NULL ,  NULL ,  0 ,  " Bridge/%s " ,  chanb - > name ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										astman_send_error ( s ,  m ,  " Unable to create temporary channels! " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_free ( tmpchana ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-06 23:12:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									do_bridge_masquerade ( chana ,  tmpchana ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									do_bridge_masquerade ( chanb ,  tmpchanb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* make the channels compatible, send error if we fail doing so */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_channel_make_compatible ( tmpchana ,  tmpchanb ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Could not make channels %s and %s compatible for manager bridge \n " ,  tmpchana - > name ,  tmpchanb - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										astman_send_error ( s ,  m ,  " Could not make channels compatible for manager bridge " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_hangup ( tmpchana ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_hangup ( tmpchanb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-06 23:12:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									/* setup the bridge thread object and start the bridge */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( tobj  =  ast_calloc ( 1 ,  sizeof ( * tobj ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Unable to spawn a new bridge thread on %s and %s: %s \n " ,  tmpchana - > name ,  tmpchanb - > name ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										astman_send_error ( s ,  m ,  " Unable to spawn a new bridge thread " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_hangup ( tmpchana ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_hangup ( tmpchanb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-06 23:12:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									tobj - > chan  =  tmpchana ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tobj - > peer  =  tmpchanb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tobj - > return_to_pbx  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_true ( playtone ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ast_strlen_zero ( xfersound )  & &  ! ast_streamfile ( tmpchanb ,  xfersound ,  tmpchanb - > language ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_waitstream ( tmpchanb ,  " " )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Failed to play a courtesy tone on chan %s \n " ,  tmpchanb - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-06 23:12:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_bridge_call_thread_launch ( tobj ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									astman_send_ack ( s ,  m ,  " Launched bridge thread with success " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-06 23:12:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ brief  CLI  command  to  list  parked  calls 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  e  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  cmd 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *   
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Check  right  usage ,  lock  parking  lot ,  display  parked  calls ,  unlock  parking  lot  list . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  CLI_SUCCESS  on  success . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  CLI_SHOWUSAGE  on  incorrect  number  of  arguments . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ retval  NULL  when  tab  completion  is  used . 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * handle_parkedcalls ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a )  
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  parkeduser  * cur ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  numparked  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ao2_iterator  iter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_parkinglot  * curlot ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > command  =  " parkedcalls show " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" Usage: parkedcalls show \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											"        List currently parked calls \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-13 23:58:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( a - > argc  >  e - > args ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  CLI_SHOWUSAGE ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-13 23:58:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  " %4s %25s (%-15s %-12s %-4s) %-6s  \n " ,  " Num " ,  " Channel " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										,  " Context " ,  " Extension " ,  " Pri " ,  " Timeout " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-04 04:01:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									iter  =  ao2_iterator_init ( parkinglots ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( curlot  =  ao2_iterator_next ( & iter ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										int  lotparked  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_cli ( a - > fd ,  " *** Parking lot: %s \n " ,  curlot - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_LIST_LOCK ( & curlot - > parkings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_LIST_TRAVERSE ( & curlot - > parkings ,  cur ,  list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cli ( a - > fd ,  " %-10.10s %25s (%-15s %-12s %-4d) %6lds \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												, cur - > parkingexten ,  cur - > chan - > name ,  cur - > context ,  cur - > exten 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-15 10:56:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												, cur - > priority , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												( long ) ( cur - > start . tv_sec  +  ( cur - > parkingtime / 1000 )  -  time ( NULL ) )  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											numparked + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											numparked  + =  lotparked ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_LIST_UNLOCK ( & curlot - > parkings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( lotparked ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_cli ( a - > fd ,  "    %d parked call%s in parking lot %s \n " ,  lotparked ,  ESS ( lotparked ) ,  curlot - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ao2_ref ( curlot ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 21:00:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_cli ( a - > fd ,  " --- \n %d parked call%s in total. \n " ,  numparked ,  ESS ( numparked ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 21:00:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2006-08-31 21:00:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  struct  ast_cli_entry  cli_features [ ]  =  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_feature_show ,  " Lists configured features " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_features_reload ,  " Reloads configured features " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-10 16:21:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									AST_CLI_DEFINE ( handle_parkedcalls ,  " List currently parked calls " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*! 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Dump  parking  lot  status 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  m 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Lock  parking  lot ,  iterate  list  and  append  parked  calls  status ,  unlock  parking  lot . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  Always  RESULT_SUCCESS  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  manager_parking_status ( struct  mansession  * s ,  const  struct  message  * m )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  parkeduser  * cur ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * id  =  astman_get_header ( m ,  " ActionID " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  idText [ 256 ]  =  " " ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ao2_iterator  iter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_parkinglot  * curlot ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ast_strlen_zero ( id ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										snprintf ( idText ,  sizeof ( idText ) ,  " ActionID: %s \r \n " ,  id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 21:00:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									astman_send_ack ( s ,  m ,  " Parked calls will follow " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									iter  =  ao2_iterator_init ( parkinglots ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									while  ( ( curlot  =  ao2_iterator_next ( & iter ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_LIST_LOCK ( & curlot - > parkings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_LIST_TRAVERSE ( & curlot - > parkings ,  cur ,  list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											astman_append ( s ,  " Event: ParkedCall \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Exten: %d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Channel: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" From: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Timeout: %ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" CallerIDNum: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" CallerIDName: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" %s " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												cur - > parkingnum ,  cur - > chan - > name ,  cur - > peername , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												( long )  cur - > start . tv_sec  +  ( long )  ( cur - > parkingtime  /  1000 )  -  ( long )  time ( NULL ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												S_OR ( cur - > chan - > cid . cid_num ,  " " ) , 	/* XXX in other places it is <unknown> */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												S_OR ( cur - > chan - > cid . cid_name ,  " " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												idText ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_LIST_UNLOCK ( & curlot - > parkings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ao2_ref ( curlot ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									astman_append ( s , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" Event: ParkedCallsComplete \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" %s " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										" \r \n " , idText ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  RESULT_SUCCESS ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  mandescr_park [ ]  =  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								" Description: Park a channel. \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								" Variables: (Names marked with * are required) \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								" 	*Channel: Channel name to park \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								" 	*Channel2: Channel to announce park info to (and return to if timeout) \n "  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								" 	Timeout: Number of milliseconds to wait before callback. \n " ;    
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Create  manager  event  for  parked  calls 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  m 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Get  channels  involved  in  park ,  create  event . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ return  Always  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								static  int  manager_park ( struct  mansession  * s ,  const  struct  message  * m )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * channel  =  astman_get_header ( m ,  " Channel " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * channel2  =  astman_get_header ( m ,  " Channel2 " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									const  char  * timeout  =  astman_get_header ( m ,  " Timeout " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  buf [ BUFSIZ ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  to  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  parkExt  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * ch1 ,  * ch2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-28 19:02:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( channel ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										astman_send_error ( s ,  m ,  " Channel not specified " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( channel2 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										astman_send_error ( s ,  m ,  " Channel2 not specified " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ch1  =  ast_get_channel_by_name_locked ( channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ch1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										snprintf ( buf ,  sizeof ( buf ) ,  " Channel does not exist: %s " ,  channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										astman_send_error ( s ,  m ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-31 18:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ch2  =  ast_get_channel_by_name_locked ( channel2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ch2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										snprintf ( buf ,  sizeof ( buf ) ,  " Channel does not exist: %s " ,  channel2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										astman_send_error ( s ,  m ,  buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_unlock ( ch1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! ast_strlen_zero ( timeout ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										sscanf ( timeout ,  " %d " ,  & to ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-13 23:58:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  =  ast_masq_park_call ( ch1 ,  ch2 ,  to ,  & parkExt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_softhangup ( ch2 ,  AST_SOFTHANGUP_EXPLICIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										astman_send_ack ( s ,  m ,  " Park successful " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										astman_send_error ( s ,  m ,  " Park failure " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_unlock ( ch1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_channel_unlock ( ch2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  find_channel_by_group ( struct  ast_channel  * c ,  void  * data )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * chan  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  ! c - > pbx  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										/* Accessing 'chan' here is safe without locking, because there is no way for
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   the  channel  do  disappear  from  under  us  at  this  point .   pickupgroup  * could * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										   change  while  we ' re  here ,  but  that  isn ' t  a  problem .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										( c  ! =  chan )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										( chan - > pickupgroup  &  c - > callgroup )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										( ( c - > _state  = =  AST_STATE_RINGING )  | |  ( c - > _state  = =  AST_STATE_RING ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Pickup  a  call 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  chan  channel  that  initiated  pickup . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Walk  list  of  channels ,  checking  it  is  not  itself ,  channel  is  pbx  one , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  check  that  the  callgroup  for  both  channels  are  the  same  and  the  channel  is  ringing . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Answer  calling  channel ,  flag  channel  as  answered  on  queue ,  masq  channels  together . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								int  ast_pickup_call ( struct  ast_channel  * chan )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2008-11-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									struct  ast_channel  * cur  =  ast_channel_search_locked ( find_channel_by_group ,  chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-05 22:19:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( cur )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-05 22:19:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										int  res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " Call pickup on chan '%s' by '%s' \n " , cur - > name ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  ast_answer ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Unable to answer '%s' \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  ast_queue_control ( chan ,  AST_CONTROL_ANSWER ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Unable to queue answer on '%s' \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										res  =  ast_channel_masquerade ( cur ,  chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " Unable to masquerade '%s' into '%s' \n " ,  chan - > name ,  cur - > name ) ; 		/* Done */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_channel_unlock ( cur ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-05 22:19:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else 	{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " No call pickup possible... \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-05 22:19:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  char  * app_bridge  =  " Bridge " ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								enum  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									BRIDGE_OPT_PLAYTONE  =  ( 1  < <  0 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								AST_APP_OPTIONS ( bridge_exec_options ,  BEGIN_OPTIONS  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_APP_OPTION ( ' p ' ,  BRIDGE_OPT_PLAYTONE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								END_OPTIONS  ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*!
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ brief  Bridge  channels 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  \ param  chan 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-05 16:31:39 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  \ param  data  channel  to  bridge  with . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  
							 
						 
					
						
							
								
									
										
										
										
											2007-08-07 23:04:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Split  data ,  check  we  aren ' t  bridging  with  ourself ,  check  valid  channel , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  answer  call  if  not  already ,  check  compatible  channels ,  setup  bridge  config 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  now  bridge  call ,  if  transfered  party  hangs  up  return  to  PBX  extension . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								*/  
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								static  int  bridge_exec ( struct  ast_channel  * chan ,  void  * data )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_channel  * current_dest_chan ,  * final_dest_chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									char  * tmp_data   =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_flags  opts  =  {  0 ,  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									struct  ast_bridge_config  bconfig  =  {  {  0 ,  } ,  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_DECLARE_APP_ARGS ( args , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( dest_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										AST_APP_ARG ( options ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_strlen_zero ( data ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Bridge require at least 1 argument specifying the other end of the bridge \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									tmp_data  =  ast_strdupa ( data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AST_STANDARD_APP_ARGS ( args ,  tmp_data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ast_strlen_zero ( args . options ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_app_parse_options ( bridge_exec_options ,  & opts ,  NULL ,  args . options ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* avoid bridge with ourselves */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! strncmp ( chan - > name ,  args . dest_chan ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										strlen ( chan - > name )  <  strlen ( args . dest_chan )  ?  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										strlen ( chan - > name )  :  strlen ( args . dest_chan ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Unable to bridge channel %s with itself \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										manager_event ( EVENT_FLAG_CALL ,  " BridgeExec " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Response: Failed \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Reason: Unable to bridge channel to itself \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Channel1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Channel2: %s \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													chan - > name ,  args . dest_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  " BRIDGERESULT " ,  " LOOP " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* make sure we have a valid end point */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( current_dest_chan  =  ast_get_channel_by_name_prefix_locked ( args . dest_chan ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										strlen ( args . dest_chan ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Bridge failed because channel %s does not exists or we  " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											" cannot get its lock \n " ,  args . dest_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										manager_event ( EVENT_FLAG_CALL ,  " BridgeExec " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Response: Failed \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Reason: Cannot grab end point \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Channel1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Channel2: %s \r \n " ,  chan - > name ,  args . dest_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  " BRIDGERESULT " ,  " NONEXISTENT " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-15 16:20:47 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_channel_unlock ( current_dest_chan ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* answer the channel if needed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( current_dest_chan - > _state  ! =  AST_STATE_UP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_answer ( current_dest_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* try to allocate a place holder where current_dest_chan will be placed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ( final_dest_chan  =  ast_channel_alloc ( 0 ,  AST_STATE_DOWN ,  NULL ,  NULL ,  NULL ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										NULL ,  NULL ,  0 ,  " Bridge/%s " ,  current_dest_chan - > name ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Cannot create placeholder channel for chan %s \n " ,  args . dest_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										manager_event ( EVENT_FLAG_CALL ,  " BridgeExec " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Response: Failed \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Reason: cannot create placeholder \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Channel1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Channel2: %s \r \n " ,  chan - > name ,  args . dest_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									do_bridge_masquerade ( current_dest_chan ,  final_dest_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* now current_dest_chan is a ZOMBIE and with softhangup set to 1 and final_dest_chan is our end point */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* try to make compatible, send error if we fail */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_channel_make_compatible ( chan ,  final_dest_chan )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_log ( LOG_WARNING ,  " Could not make channels %s and %s compatible for bridge \n " ,  chan - > name ,  final_dest_chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										manager_event ( EVENT_FLAG_CALL ,  " BridgeExec " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Response: Failed \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Reason: Could not make channels compatible for bridge \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Channel1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
													" Channel2: %s \r \n " ,  chan - > name ,  final_dest_chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										ast_hangup ( final_dest_chan ) ;  /* may be we should return this channel to the PBX? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										pbx_builtin_setvar_helper ( chan ,  " BRIDGERESULT " ,  " INCOMPATIBLE " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* Report that the bridge will be successfull */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									manager_event ( EVENT_FLAG_CALL ,  " BridgeExec " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Response: Success \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Channel1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												" Channel2: %s \r \n " ,  chan - > name ,  final_dest_chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* we have 2 valid channels to bridge, now it is just a matter of setting up the bridge config and starting the bridge */ 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ast_test_flag ( & opts ,  BRIDGE_OPT_PLAYTONE )  & &  ! ast_strlen_zero ( xfersound ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ! ast_streamfile ( final_dest_chan ,  xfersound ,  final_dest_chan - > language ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  ( ast_waitstream ( final_dest_chan ,  " " )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												ast_log ( LOG_WARNING ,  " Failed to play courtesy tone on %s \n " ,  final_dest_chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* do the bridge */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									ast_bridge_call ( chan ,  final_dest_chan ,  & bconfig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									/* the bridge has ended, set BRIDGERESULT to SUCCESS. If the other channel has not been hung up, return it to the PBX */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									pbx_builtin_setvar_helper ( chan ,  " BRIDGERESULT " ,  " SUCCESS " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  ( ! ast_check_hangup ( final_dest_chan ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " starting new PBX in %s,%s,%d for chan %s \n " ,  
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											final_dest_chan - > context ,  final_dest_chan - > exten ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											final_dest_chan - > priority ,  final_dest_chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  ( ast_pbx_start ( final_dest_chan )  ! =  AST_PBX_SUCCESS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_log ( LOG_WARNING ,  " FAILED continuing PBX on dest chan %s \n " ,  final_dest_chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_hangup ( final_dest_chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											ast_debug ( 1 ,  " SUCCESS continuing PBX on chan %s \n " ,  final_dest_chan - > name ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_debug ( 1 ,  " hangup chan %s since the other endpoint has hung up \n " ,  final_dest_chan - > name ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_hangup ( final_dest_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-23 23:09:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								int  ast_features_init ( void )  
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-11-01 21:10:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_register_application2 ( app_bridge ,  bridge_exec ,  NULL ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									parkinglots  =  ao2_container_alloc ( 7 ,  parkinglot_hash_cb ,  parkinglot_cmp_cb ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-23 02:22:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:03:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ( res  =  load_config ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-05 10:31:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_cli_register_multiple ( cli_features ,  ARRAY_LEN ( cli_features ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-08 17:15:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									ast_pthread_create ( & parking_thread ,  NULL ,  do_parking_thread ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-01 21:10:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									res  =  ast_register_application2 ( parkedcall ,  park_exec ,  NULL ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-03 06:31:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! res ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-01 21:10:07 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										res  =  ast_register_application2 ( parkcall ,  park_call_exec ,  NULL ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-01-30 05:49:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  ( ! res )  { 
							 
						 
					
						
							
								
									
										
											 
										
											
												Merge changes from team/russell/issue_5841:
This patch adds a "Bridge" Manager action, as well as a "Bridge" dialplan
application.  The manager action will allow you to steal two active channels
in the system and bridge them together.  Then, the one that did not hang up
will continue in the dialplan.  Using the application will bridge the calling
channel to an arbitrary channel in the system.  Whichever channel does not
hang up here will continue in the dialplan, as well.
This patch has been touched by a bunch of people over the course of a couple
years.  Please forgive me if I have missed your name in the history of things.
The most recent patch came from issue #5841, but there is also a reference to
an earlier version of this patch from issue #4297.  The people involved in writing
and/or reviewing the code include at least: twisted, mflorrel, heath1444, davetroy, 
tim_ringenbach, moy, tmancill, serge-v, and me.  There are also positive test
reports from many people.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@61281 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-04-10 20:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_manager_register ( " ParkedCalls " ,  0 ,  manager_parking_status ,  " List parked calls " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-21 23:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_manager_register2 ( " Park " ,  EVENT_FLAG_CALL ,  manager_park ,  " Park a channel " ,  mandescr_park ) ;  
							 
						 
					
						
							
								
									
										
										
										
											2008-01-10 00:12:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										ast_manager_register2 ( " Bridge " ,  EVENT_FLAG_CALL ,  action_bridge ,  " Bridge two channels already in the PBX " ,  mandescr_bridge ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-01-30 05:49:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
											
												METERMAIDS:
-----------
- Adding devicestate providers, a new architecture to add non-channel related
  device state information, like parking lots, queues, meetmes, vending machines
  and Windows 98 reboots (lots of blinking on those lights)
- Adding provider for parking lots, so you can subscribe to the status of a
  parking lot
- Adding provider for meetme, so you can have a blinking lamp for a meetme
  ( Example: exten => edvina,hint,meetme:1234 )
- Adding support for directed parking - set the PARKINGEXTEN before you manually
  call Park() and you will be parked on that space. If it's occupied, dialplan
  execution will continue.
This work was sponsored by Voop A/S - www.voop.com
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@36055 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-06-26 16:43:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									res  | =  ast_devstate_prov_add ( " Park " ,  metermaidstate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-12-27 11:07:33 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}