2004-08-27 22:53:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-14 20:46:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 *  Asterisk  - -  An  open  source  telephony  toolkit . 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-03 22:16:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 *  Copyright  ( C )  1999  -  2006 ,  Digium ,  Inc . 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-27 03:28:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 *  Mark  Spencer  < markster @ digium . com > 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +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 . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 *  This  program  is  free  software ,  distributed  under  the  terms  of 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-14 20:46:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 *  the  GNU  General  Public  License  Version  2.  See  the  LICENSE  file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  at  the  top  of  the  source  tree . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-24 20:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \file
 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-14 20:46:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-24 20:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 *  \ brief  Channel  Management 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-30 21:18:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ author  Mark  Spencer  < markster @ digium . com > 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-07 18:54:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								ASTERISK_FILE_VERSION ( __FILE__ ,  " $Revision$ " ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-20 22:18:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/_private.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# include  <sys/time.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <signal.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-07 18:54:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <math.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-24 17:11:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-20 23:16:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/paths.h"	/* use ast_config_AST_SYSTEM_NAME */ 
 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-22 13:11:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-21 06:02:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/pbx.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/frame.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-16 17:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/mod_format.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-21 06:02:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/sched.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/channel.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/musiconhold.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/say.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/file.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/cli.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/translate.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/manager.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/cel.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-21 06:02:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/chanvars.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/linkedlists.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/indications.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/monitor.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/causes.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/callerid.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-21 06:02:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/utils.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/lock.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/app.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asterisk/transcap.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/devicestate.h" 
 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merge team/russell/ast_verbose_threadstorage
- instead of defining a free() wrapper in a bunch of files, define it as
  ast_free() in utils.h and remove the copies from all the files.
- centralize and abstract the code used for doing thread storage. The code
  lives in threadstorage.h, with one function being implemented in utils.c.
  This new API includes generic thread storage as well as special functions
  for handling thread local dynamic length string buffers.
- update ast_inet_ntoa() to use the new threadstorage API
- update ast_state2str() to use the new threadstorage API
- update ast_cli() to use the new threadstorage API
- Modify manager_event() to use thread storage. Instead of using a buffer of
  4096 characters as the workspace for building the manager event, use a thread
  local dynamic string.  Now there is no length limitation on the length of the
  body of a manager event.
- Significantly simplify the handling of ast_verbose() ...
  - Instead of using a static char buffer and a lock to make sure only one
    thread can be using ast_verbose() at a time, use a thread local dynamic
    string as the workspace for preparing the verbose message. Instead of
    locking around the entire function, the only locking done now is when the
    message has been built and is being deliviered to the list of registered
    verbose message handlers.
  - This function was doing a strdup() on every message passed to it and
    keeping a queue of the last 200 messages in memory. This has been
    completely removed. The only place this was used was that if there were
    any messages in the verbose queue when a verbose handler was registered,
    all of the messages in the queue would be fed to it.  So, I just made sure
    that the console verbose handler and the network verbose handler (for
    remote asterisk consoles) were registered before any verbose messages.
    pbx_gtkconsole and pbx_kdeconsole will now lose a few verbose messages at
    startup, but I didn't feel the performance hit of this message queue was
    worth saving the initial verbose output for these very rarely used modules.
  - I have removed the last three arguments to the verbose handlers, leaving
    only the string itself because they aren't needed anymore. For example,
    ast_verbose had some logic for telling the verbose handler to add
    a newline if the buffer was completely full. Now that the buffer can grow
    as needed, this doesn't matter anymore.
  - remove unused function, ast_verbose_dmesg() which was to dispatch the
    message queue
  - Convert the list of verbose handlers to use the linked list macros.
- add missing newline characters to a few ast_verbose() calls
- convert the list of log channels to use the linked list macros in logger.c
- fix close_logger() to close all of the files it opened for logging
- update ast_log() to use a thread local dynamic string for its workspace
  for preparing log messages instead of a buffer of size BUFSIZ (8kB on my
  system) allocated on the stack.  The dynamic string in this case is limited
  to only growing to a maximum size of BUFSIZ.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@39272 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-08-08 06:32:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/threadstorage.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-28 18:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/slinfactory.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 19:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/audiohook.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/framehook.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 12:45:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/timing.h" 
 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/autochan.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/stringfields.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-08 05:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/global_datastores.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 18:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  "asterisk/data.h" 
 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-28 18:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef HAVE_EPOLL 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <sys/epoll.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 19:12:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# if defined(HAVE_PRI) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "libpri.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif	 /* defined(HAVE_PRI) */ 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif	 /* defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) */ 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_epoll_data  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  which ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-08-28 20:02:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* uncomment if you have problems with 'monitoring' synchronized files */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								#if 0 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define MONITOR_CONSTANT_DELAY 
 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-24 20:29:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define MONITOR_DELAY	150 * 8		 /*!< 150 ms of MONITORING DELAY */ 
 
							 
						 
					
						
							
								
									
										
										
										
											2003-08-28 20:02:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-24 20:29:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Prevent new channel allocation if shutting down. */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-12-27 22:14:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  shutting_down ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-06 02:29:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-12-27 22:14:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  uniqueint ; 
							 
						 
					
						
							
								
									
										
										
										
											2000-01-02 20:59:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-12-27 22:14:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								unsigned  long  global_fin ,  global_fout ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-11-06 21:33:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-10-19 01:00:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								AST_THREADSTORAGE ( state2str_threadbuf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-21 22:36:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define STATE2STR_BUFSIZE   32 
 
							 
						 
					
						
							
								
									
										
										
										
											2000-01-02 20:59:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-04-24 19:03:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! Default amount of time to use when emulating a digit as a begin and end 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *   100 ms  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define AST_DEFAULT_EMULATE_DTMF_DURATION 100 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! Minimum allowed digit length - 80ms */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define AST_MIN_DTMF_DURATION 80 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! Minimum amount of time between the end of the last digit and the beginning 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *   of  a  new  one  -  45 ms  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define AST_MIN_DTMF_GAP 45 
 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-24 20:29:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief List of channel drivers */ 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								struct  chanlist  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  struct  ast_channel_tech  * tech ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 05:05:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_LIST_ENTRY ( chanlist )  list ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-06 02:29:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 04:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef CHANNEL_TRACE 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \brief Structure to hold channel context backtrace data */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_chan_trace_data  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  enabled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_LIST_HEAD_NOLOCK ( ,  ast_chan_trace )  trace ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \brief Structure to save contexts where an ast_chan has been into */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_chan_trace  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  context [ AST_MAX_CONTEXT ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  exten [ AST_MAX_EXTENSION ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  priority ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_LIST_ENTRY ( ast_chan_trace )  entry ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-24 20:29:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief the list of registered channel types */ 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  AST_RWLIST_HEAD_STATIC ( backends ,  chanlist ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-06 02:29:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef LOW_MEMORY 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define NUM_CHANNEL_BUCKETS 61 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# else 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# define NUM_CHANNEL_BUCKETS 1567 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								#if 0 	/* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define DATA_EXPORT_CALLERID(MEMBER)				\ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_callerid ,  cid_dnid ,  AST_DATA_STRING ) 		\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_callerid ,  cid_num ,  AST_DATA_STRING ) 		\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_callerid ,  cid_name ,  AST_DATA_STRING ) 		\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_callerid ,  cid_ani ,  AST_DATA_STRING ) 		\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_callerid ,  cid_pres ,  AST_DATA_INTEGER ) 	\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_callerid ,  cid_ani2 ,  AST_DATA_INTEGER ) 	\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_callerid ,  cid_tag ,  AST_DATA_STRING ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								AST_DATA_STRUCTURE ( ast_callerid ,  DATA_EXPORT_CALLERID ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 18:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define DATA_EXPORT_CHANNEL(MEMBER)						\ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  blockproc ,  AST_DATA_STRING ) 				\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  appl ,  AST_DATA_STRING ) 				\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  data ,  AST_DATA_STRING ) 				\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  name ,  AST_DATA_STRING ) 				\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  language ,  AST_DATA_STRING ) 				\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  musicclass ,  AST_DATA_STRING ) 			\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  accountcode ,  AST_DATA_STRING ) 			\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  peeraccount ,  AST_DATA_STRING ) 			\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  userfield ,  AST_DATA_STRING ) 				\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  call_forward ,  AST_DATA_STRING ) 			\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  uniqueid ,  AST_DATA_STRING ) 				\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  linkedid ,  AST_DATA_STRING ) 				\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  parkinglot ,  AST_DATA_STRING ) 			\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  hangupsource ,  AST_DATA_STRING ) 			\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  dialcontext ,  AST_DATA_STRING ) 			\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  rings ,  AST_DATA_INTEGER ) 				\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  priority ,  AST_DATA_INTEGER ) 				\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  macropriority ,  AST_DATA_INTEGER ) 			\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  adsicpe ,  AST_DATA_INTEGER ) 				\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  fin ,  AST_DATA_UNSIGNED_INTEGER ) 			\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  fout ,  AST_DATA_UNSIGNED_INTEGER ) 			\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  emulate_dtmf_duration ,  AST_DATA_UNSIGNED_INTEGER ) 	\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  visible_indication ,  AST_DATA_INTEGER ) 		\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  context ,  AST_DATA_STRING ) 				\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  exten ,  AST_DATA_STRING ) 				\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  macrocontext ,  AST_DATA_STRING ) 			\
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									MEMBER ( ast_channel ,  macroexten ,  AST_DATA_STRING ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								AST_DATA_STRUCTURE ( ast_channel ,  DATA_EXPORT_CHANNEL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief All active channels on the system */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  struct  ao2_container  * channels ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-24 20:29:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief map AST_CAUSE's to readable string representations 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ ref  causes . h 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*/ 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-16 02:54:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  const  struct  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-05 17:16:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  cause ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-25 20:51:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  char  * name ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-05 17:16:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  char  * desc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}  causes [ ]  =  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-25 20:51:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_UNALLOCATED ,  " UNALLOCATED " ,  " Unallocated (unassigned) number "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_NO_ROUTE_TRANSIT_NET ,  " NO_ROUTE_TRANSIT_NET " ,  " No route to specified transmit network "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_NO_ROUTE_DESTINATION ,  " NO_ROUTE_DESTINATION " ,  " No route to destination "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_CHANNEL_UNACCEPTABLE ,  " CHANNEL_UNACCEPTABLE " ,  " Channel unacceptable "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_CALL_AWARDED_DELIVERED ,  " CALL_AWARDED_DELIVERED " ,  " Call awarded and being delivered in an established channel "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_NORMAL_CLEARING ,  " NORMAL_CLEARING " ,  " Normal Clearing "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_USER_BUSY ,  " USER_BUSY " ,  " User busy "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_NO_USER_RESPONSE ,  " NO_USER_RESPONSE " ,  " No user responding "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_NO_ANSWER ,  " NO_ANSWER " ,  " User alerting, no answer "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_CALL_REJECTED ,  " CALL_REJECTED " ,  " Call Rejected "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_NUMBER_CHANGED ,  " NUMBER_CHANGED " ,  " Number changed "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_DESTINATION_OUT_OF_ORDER ,  " DESTINATION_OUT_OF_ORDER " ,  " Destination out of order "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_INVALID_NUMBER_FORMAT ,  " INVALID_NUMBER_FORMAT " ,  " Invalid number format "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_FACILITY_REJECTED ,  " FACILITY_REJECTED " ,  " Facility rejected "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_RESPONSE_TO_STATUS_ENQUIRY ,  " RESPONSE_TO_STATUS_ENQUIRY " ,  " Response to STATus ENQuiry "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_NORMAL_UNSPECIFIED ,  " NORMAL_UNSPECIFIED " ,  " Normal, unspecified "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_NORMAL_CIRCUIT_CONGESTION ,  " NORMAL_CIRCUIT_CONGESTION " ,  " Circuit/channel congestion "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_NETWORK_OUT_OF_ORDER ,  " NETWORK_OUT_OF_ORDER " ,  " Network out of order "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_NORMAL_TEMPORARY_FAILURE ,  " NORMAL_TEMPORARY_FAILURE " ,  " Temporary failure "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_SWITCH_CONGESTION ,  " SWITCH_CONGESTION " ,  " Switching equipment congestion "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_ACCESS_INFO_DISCARDED ,  " ACCESS_INFO_DISCARDED " ,  " Access information discarded "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_REQUESTED_CHAN_UNAVAIL ,  " REQUESTED_CHAN_UNAVAIL " ,  " Requested channel not available "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_PRE_EMPTED ,  " PRE_EMPTED " ,  " Pre-empted "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_FACILITY_NOT_SUBSCRIBED ,  " FACILITY_NOT_SUBSCRIBED " ,  " Facility not subscribed "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_OUTGOING_CALL_BARRED ,  " OUTGOING_CALL_BARRED " ,  " Outgoing call barred "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_INCOMING_CALL_BARRED ,  " INCOMING_CALL_BARRED " ,  " Incoming call barred "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_BEARERCAPABILITY_NOTAUTH ,  " BEARERCAPABILITY_NOTAUTH " ,  " Bearer capability not authorized "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_BEARERCAPABILITY_NOTAVAIL ,  " BEARERCAPABILITY_NOTAVAIL " ,  " Bearer capability not available "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_BEARERCAPABILITY_NOTIMPL ,  " BEARERCAPABILITY_NOTIMPL " ,  " Bearer capability not implemented "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_CHAN_NOT_IMPLEMENTED ,  " CHAN_NOT_IMPLEMENTED " ,  " Channel not implemented "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_FACILITY_NOT_IMPLEMENTED ,  " FACILITY_NOT_IMPLEMENTED " ,  " Facility not implemented "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_INVALID_CALL_REFERENCE ,  " INVALID_CALL_REFERENCE " ,  " Invalid call reference value "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_INCOMPATIBLE_DESTINATION ,  " INCOMPATIBLE_DESTINATION " ,  " Incompatible destination "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_INVALID_MSG_UNSPECIFIED ,  " INVALID_MSG_UNSPECIFIED " ,  " Invalid message unspecified "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_MANDATORY_IE_MISSING ,  " MANDATORY_IE_MISSING " ,  " Mandatory information element is missing "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_MESSAGE_TYPE_NONEXIST ,  " MESSAGE_TYPE_NONEXIST " ,  " Message type nonexist. "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_WRONG_MESSAGE ,  " WRONG_MESSAGE " ,  " Wrong message "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_IE_NONEXIST ,  " IE_NONEXIST " ,  " Info. element nonexist or not implemented "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_INVALID_IE_CONTENTS ,  " INVALID_IE_CONTENTS " ,  " Invalid information element contents "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_WRONG_CALL_STATE ,  " WRONG_CALL_STATE " ,  " Message not compatible with call state "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_RECOVERY_ON_TIMER_EXPIRE ,  " RECOVERY_ON_TIMER_EXPIRE " ,  " Recover on timer expiry "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_MANDATORY_IE_LENGTH_ERROR ,  " MANDATORY_IE_LENGTH_ERROR " ,  " Mandatory IE length error "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_PROTOCOL_ERROR ,  " PROTOCOL_ERROR " ,  " Protocol error, unspecified "  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{  AST_CAUSE_INTERWORKING ,  " INTERWORKING " ,  " Interworking, unspecified "  } , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-05 17:16:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-11 07:06:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_variable  * ast_channeltype_list ( void ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  chanlist  * cl ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_variable  * var  =  NULL ,  * prev  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_RWLIST_RDLOCK ( & backends ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_RWLIST_TRAVERSE ( & backends ,  cl ,  list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-11 07:06:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( prev )   { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-29 20:55:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ( prev - > next  =  ast_variable_new ( cl - > tech - > type ,  cl - > tech - > description ,  " " ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-11 07:06:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												prev  =  prev - > next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-29 20:55:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											var  =  ast_variable_new ( cl - > tech - > type ,  cl - > tech - > description ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-11 07:06:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											prev  =  var ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-11 07:06:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  var ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  channel_data_add_flags ( struct  ast_data  * tree , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " DEFER_DTMF " ,  ast_test_flag ( chan ,  AST_FLAG_DEFER_DTMF ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " WRITE_INT " ,  ast_test_flag ( chan ,  AST_FLAG_WRITE_INT ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " BLOCKING " ,  ast_test_flag ( chan ,  AST_FLAG_BLOCKING ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " ZOMBIE " ,  ast_test_flag ( chan ,  AST_FLAG_ZOMBIE ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " EXCEPTION " ,  ast_test_flag ( chan ,  AST_FLAG_EXCEPTION ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " MOH " ,  ast_test_flag ( chan ,  AST_FLAG_MOH ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " SPYING " ,  ast_test_flag ( chan ,  AST_FLAG_SPYING ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " NBRIDGE " ,  ast_test_flag ( chan ,  AST_FLAG_NBRIDGE ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " IN_AUTOLOOP " ,  ast_test_flag ( chan ,  AST_FLAG_IN_AUTOLOOP ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " OUTGOING " ,  ast_test_flag ( chan ,  AST_FLAG_OUTGOING ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " IN_DTMF " ,  ast_test_flag ( chan ,  AST_FLAG_IN_DTMF ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " EMULATE_DTMF " ,  ast_test_flag ( chan ,  AST_FLAG_EMULATE_DTMF ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " END_DTMF_ONLY " ,  ast_test_flag ( chan ,  AST_FLAG_END_DTMF_ONLY ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " ANSWERED_ELSEWHERE " ,  ast_test_flag ( chan ,  AST_FLAG_ANSWERED_ELSEWHERE ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " MASQ_NOSTREAM " ,  ast_test_flag ( chan ,  AST_FLAG_MASQ_NOSTREAM ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " BRIDGE_HANGUP_RUN " ,  ast_test_flag ( chan ,  AST_FLAG_BRIDGE_HANGUP_RUN ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " BRIDGE_HANGUP_DONT " ,  ast_test_flag ( chan ,  AST_FLAG_BRIDGE_HANGUP_DONT ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( tree ,  " DISABLE_WORKAROUNDS " ,  ast_test_flag ( chan ,  AST_FLAG_DISABLE_WORKAROUNDS ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  const  char  * party_number_ton2str ( int  ton ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 19:12:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# if defined(HAVE_PRI) 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									switch  ( ( ton  > >  4 )  &  0x07 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  PRI_TON_INTERNATIONAL : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  " International " ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  PRI_TON_NATIONAL : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  " National " ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  PRI_TON_NET_SPECIFIC : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  " Network Specific " ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  PRI_TON_SUBSCRIBER : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  " Subscriber " ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  PRI_TON_ABBREVIATED : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  " Abbreviated " ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  PRI_TON_RESERVED : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  " Reserved " ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  PRI_TON_UNKNOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 19:12:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif	 /* defined(HAVE_PRI) */ 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  " Unknown " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif	 /* defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) */ 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# if defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  const  char  * party_number_plan2str ( int  plan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# if defined(HAVE_PRI) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( plan  &  0x0F )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  PRI_NPI_UNKNOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  PRI_NPI_E163_E164 : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-12 17:54:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  " Public (E.163/E.164) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  PRI_NPI_X121 : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-12 17:54:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  " Data (X.121) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  PRI_NPI_F69 : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-12 17:54:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  " Telex (F.69) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  PRI_NPI_NATIONAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " National Standard " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  PRI_NPI_PRIVATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Private " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  PRI_NPI_RESERVED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Reserved " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif	 /* defined(HAVE_PRI) */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  " Unknown " ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif	 /* defined(KEEP_TILL_CHANNEL_PARTY_NUMBER_INFO_NEEDED) */ 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_data_add_structure ( struct  ast_data  * tree , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * chan ,  int  add_bridged ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 18:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * bc ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_data  * data_bridged ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_data  * data_cdr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_data  * data_flags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_data  * data_zones ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_data  * enum_node ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_data  * data_softhangup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								#if 0 	/* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_data  * data_callerid ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  value_str [ 100 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! tree )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_structure ( ast_channel ,  tree ,  chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( add_bridged )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										bc  =  ast_bridged_channel ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( bc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											data_bridged  =  ast_data_add_node ( tree ,  " bridged " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ! data_bridged )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_data_add_structure ( data_bridged ,  bc ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_codecs ( tree ,  " oldwriteformat " ,  chan - > oldwriteformat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_codecs ( tree ,  " nativeformats " ,  chan - > nativeformats ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_codecs ( tree ,  " readformat " ,  chan - > readformat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_codecs ( tree ,  " writeformat " ,  chan - > writeformat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_codecs ( tree ,  " rawreadformat " ,  chan - > rawreadformat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_codecs ( tree ,  " rawwriteformat " ,  chan - > rawwriteformat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* state */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enum_node  =  ast_data_add_node ( tree ,  " state " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! enum_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_str ( enum_node ,  " text " ,  ast_state2str ( chan - > _state ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_int ( enum_node ,  " value " ,  chan - > _state ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* hangupcause */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enum_node  =  ast_data_add_node ( tree ,  " hangupcause " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! enum_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_str ( enum_node ,  " text " ,  ast_cause2str ( chan - > hangupcause ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_int ( enum_node ,  " value " ,  chan - > hangupcause ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* amaflags */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enum_node  =  ast_data_add_node ( tree ,  " amaflags " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! enum_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_str ( enum_node ,  " text " ,  ast_cdr_flags2str ( chan - > amaflags ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_int ( enum_node ,  " value " ,  chan - > amaflags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* transfercapability */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enum_node  =  ast_data_add_node ( tree ,  " transfercapability " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! enum_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_str ( enum_node ,  " text " ,  ast_transfercapability2str ( chan - > transfercapability ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_int ( enum_node ,  " value " ,  chan - > transfercapability ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* _softphangup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data_softhangup  =  ast_data_add_node ( tree ,  " softhangup " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! data_softhangup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( data_softhangup ,  " dev " ,  chan - > _softhangup  &  AST_SOFTHANGUP_DEV ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( data_softhangup ,  " asyncgoto " ,  chan - > _softhangup  &  AST_SOFTHANGUP_ASYNCGOTO ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( data_softhangup ,  " shutdown " ,  chan - > _softhangup  &  AST_SOFTHANGUP_SHUTDOWN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( data_softhangup ,  " timeout " ,  chan - > _softhangup  &  AST_SOFTHANGUP_TIMEOUT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( data_softhangup ,  " appunload " ,  chan - > _softhangup  &  AST_SOFTHANGUP_APPUNLOAD ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( data_softhangup ,  " explicit " ,  chan - > _softhangup  &  AST_SOFTHANGUP_EXPLICIT ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_bool ( data_softhangup ,  " unbridge " ,  chan - > _softhangup  &  AST_SOFTHANGUP_UNBRIDGE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* channel flags */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data_flags  =  ast_data_add_node ( tree ,  " flags " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! data_flags )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									channel_data_add_flags ( data_flags ,  chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_uint ( tree ,  " timetohangup " ,  chan - > whentohangup . tv_sec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								#if 0 	/* XXX AstData: ast_callerid no longer exists. (Equivalent code not readily apparent.) */
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* callerid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data_callerid  =  ast_data_add_node ( tree ,  " callerid " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! data_callerid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_structure ( ast_callerid ,  data_callerid ,  & ( chan - > cid ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* insert the callerid ton */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enum_node  =  ast_data_add_node ( data_callerid ,  " cid_ton " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! enum_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_int ( enum_node ,  " value " ,  chan - > cid . cid_ton ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 22:05:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									snprintf ( value_str ,  sizeof ( value_str ) ,  " TON: %s/Plan: %s " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										party_number_ton2str ( chan - > cid . cid_ton ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										party_number_plan2str ( chan - > cid . cid_ton ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_add_str ( enum_node ,  " text " ,  value_str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* tone zone */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan - > zone )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										data_zones  =  ast_data_add_node ( tree ,  " zone " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! data_zones )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_tone_zone_data_add_structure ( data_zones ,  chan - > zone ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* insert cdr */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data_cdr  =  ast_data_add_node ( tree ,  " cdr " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! data_cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_cdr_data_add_structure ( data_cdr ,  chan - > cdr ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 18:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_data_cmp_structure ( const  struct  ast_data_search  * tree , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * chan ,  const  char  * structure_name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ast_data_search_cmp_structure ( tree ,  ast_channel ,  chan ,  structure_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-24 20:29:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Show channel types - CLI command */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  char  * handle_cli_core_show_channeltypes ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-31 00:04:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-04 09:22:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# define FORMAT  "%-10.10s  %-40.40s %-12.12s %-12.12s %-12.12s\n" 
 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-24 05:18:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  chanlist  * cl ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-04 09:22:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  count_chan  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										e - > command  =  " core show channeltypes " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" Usage: core show channeltypes \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											"        Lists available channel types registered in your \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											"        Asterisk server. \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( a - > argc  ! =  3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  CLI_SHOWUSAGE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_cli ( a - > fd ,  FORMAT ,  " Type " ,  " Description " ,        " Devicestate " ,  " Indications " ,  " Transfer " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_cli ( a - > fd ,  FORMAT ,  " ---------- " ,  " ----------- " ,  " ----------- " ,  " ----------- " ,  " -------- " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-24 03:30:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_RDLOCK ( & backends ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_RWLIST_TRAVERSE ( & backends ,  cl ,  list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_cli ( a - > fd ,  FORMAT ,  cl - > tech - > type ,  cl - > tech - > description , 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											( cl - > tech - > devicestate )  ?  " yes "  :  " no " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											( cl - > tech - > indicate )  ?  " yes "  :  " no " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											( cl - > tech - > transfer )  ?  " yes "  :  " no " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-04 09:22:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										count_chan + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-31 00:04:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-24 03:30:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_cli ( a - > fd ,  " ---------- \n %d channel drivers registered. \n " ,  count_chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-24 03:30:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-31 00:04:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-02 21:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# undef FORMAT 
 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  char  * complete_channeltypes ( struct  ast_cli_args  * a ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  chanlist  * cl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  which  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  wordlen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  * ret  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-02 21:37:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( a - > pos  ! =  3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									wordlen  =  strlen ( a - > word ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_RDLOCK ( & backends ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_RWLIST_TRAVERSE ( & backends ,  cl ,  list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! strncasecmp ( a - > word ,  cl - > tech - > type ,  wordlen )  & &  + + which  >  a - > n )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ret  =  ast_strdup ( cl - > tech - > type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ret ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-31 00:04:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-24 20:29:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Show details about a channel driver - CLI command */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  char  * handle_cli_core_show_channeltype ( struct  ast_cli_entry  * e ,  int  cmd ,  struct  ast_cli_args  * a ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-22 02:23:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  chanlist  * cl  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  buf [ 512 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-22 02:23:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									switch  ( cmd )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  CLI_INIT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										e - > command  =  " core show channeltype " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										e - > usage  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" Usage: core show channeltype <name> \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" 	Show details about the specified channel type, <name>. \n " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  CLI_GENERATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  complete_channeltypes ( a ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( a - > argc  ! =  4 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  CLI_SHOWUSAGE ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-22 02:23:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_RDLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-22 02:23:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_TRAVERSE ( & backends ,  cl ,  list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! strncasecmp ( cl - > tech - > type ,  a - > argv [ 3 ] ,  strlen ( cl - > tech - > type ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-22 02:23:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! cl )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_cli ( a - > fd ,  " \n %s is not a registered channel driver. \n " ,  a - > argv [ 3 ] ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  CLI_FAILURE ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-22 02:23:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_cli ( a - > fd , 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-22 02:23:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										" -- Info about channel driver: %s -- \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										"   Device State: %s \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										"     Indication: %s \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										"      Transfer : %s \n " 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										"   Capabilities: %s \n " 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										"    Digit Begin: %s \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										"      Digit End: %s \n " 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-22 02:23:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										"     Send HTML : %s \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										"  Image Support: %s \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										"   Text Support: %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cl - > tech - > type , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										( cl - > tech - > devicestate )  ?  " yes "  :  " no " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										( cl - > tech - > indicate )  ?  " yes "  :  " no " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										( cl - > tech - > transfer )  ?  " yes "  :  " no " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_getformatname_multiple ( buf ,  sizeof ( buf ) ,  ( cl - > tech - > capabilities )  ?  cl - > tech - > capabilities  :  - 1 ) , 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										( cl - > tech - > send_digit_begin )  ?  " yes "  :  " no " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										( cl - > tech - > send_digit_end )  ?  " yes "  :  " no " , 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-22 02:23:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										( cl - > tech - > send_html )  ?  " yes "  :  " no " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										( cl - > tech - > send_image )  ?  " yes "  :  " no " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										( cl - > tech - > send_text )  ?  " yes "  :  " no " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-10-11 19:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  CLI_SUCCESS ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-22 02:23:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:54:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  struct  ast_cli_entry  cli_channel [ ]  =  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-22 20:05:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_CLI_DEFINE ( handle_cli_core_show_channeltypes ,  " List available channel types " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CLI_DEFINE ( handle_cli_core_show_channeltype ,   " Give more details on that channel type " ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-18 19:54:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-22 02:23:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-05-25 16:23:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  struct  ast_frame  * kill_read ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Hangup channel. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  struct  ast_frame  * kill_exception ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Hangup channel. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  kill_write ( struct  ast_channel  * chan ,  struct  ast_frame  * frame ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Hangup channel. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  kill_fixup ( struct  ast_channel  * oldchan ,  struct  ast_channel  * newchan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* No problem fixing up the channel. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  kill_hangup ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									chan - > tech_pvt  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Kill  the  channel  channel  driver  technology  descriptor . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ details 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  The  purpose  of  this  channel  technology  is  to  encourage  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  channel  to  hangup  as  quickly  as  possible . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ note  Used  by  DTMF  atxfer  and  zombie  channels . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								const  struct  ast_channel_tech  ast_kill_tech  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. type  =  " Kill " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. description  =  " Kill channel (should not see this) " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. capabilities  =  - 1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. read  =  kill_read , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. exception  =  kill_exception , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. write  =  kill_write , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. fixup  =  kill_fixup , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. hangup  =  kill_hangup , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 04:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef CHANNEL_TRACE 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \brief Destructor for the channel trace datastore */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  ast_chan_trace_destroy_cb ( void  * data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_chan_trace  * trace ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_chan_trace_data  * traced  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									while  ( ( trace  =  AST_LIST_REMOVE_HEAD ( & traced - > trace ,  entry ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_free ( trace ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_free ( traced ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \brief Datastore to put the linked list of ast_chan_trace and trace status */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-09 11:30:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  const  struct  ast_datastore_info  ast_chan_trace_datastore_info  =  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 04:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									. type  =  " ChanTrace " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. destroy  =  ast_chan_trace_destroy_cb 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \brief Put the channel backtrace in a string */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_trace_serialize ( struct  ast_channel  * chan ,  struct  ast_str  * * buf ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  total  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_chan_trace  * trace ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_chan_trace_data  * traced ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * store ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									store  =  ast_channel_datastore_find ( chan ,  & ast_chan_trace_datastore_info ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! store )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  total ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									traced  =  store - > data ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-10-31 09:31:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_str_reset ( * buf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 04:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_LIST_TRAVERSE ( & traced - > trace ,  trace ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ast_str_append ( buf ,  0 ,  " [%d] => %s, %s, %d \n " ,  total ,  trace - > context ,  trace - > exten ,  trace - > priority )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_ERROR ,  " Data Buffer Size Exceeded! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											total  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										total + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  total ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* !\brief Whether or not context tracing is enabled */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_trace_is_enabled ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * store  =  ast_channel_datastore_find ( chan ,  & ast_chan_trace_datastore_info ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! store ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ( ( struct  ast_chan_trace_data  * ) store - > data ) - > enabled ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \brief Update the context backtrace data if tracing is enabled */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  ast_channel_trace_data_update ( struct  ast_channel  * chan ,  struct  ast_chan_trace_data  * traced ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_chan_trace  * trace ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! traced - > enabled ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* If the last saved context does not match the current one
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									   OR  we  have  not  saved  any  context  so  far ,  then  save  the  current  context  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( ! AST_LIST_EMPTY ( & traced - > trace )  & &  strcasecmp ( AST_LIST_FIRST ( & traced - > trace ) - > context ,  chan - > context ) )  | |  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									    ( AST_LIST_EMPTY ( & traced - > trace ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Just do some debug logging */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( AST_LIST_EMPTY ( & traced - > trace ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_DEBUG ,  " Setting initial trace context to %s \n " ,  chan - > context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_DEBUG ,  " Changing trace context from %s to %s \n " ,  AST_LIST_FIRST ( & traced - > trace ) - > context ,  chan - > context ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* alloc or bail out */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										trace  =  ast_malloc ( sizeof ( * trace ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! trace )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* save the current location and store it in the trace list */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_copy_string ( trace - > context ,  chan - > context ,  sizeof ( trace - > context ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_copy_string ( trace - > exten ,  chan - > exten ,  sizeof ( trace - > exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										trace - > priority  =  chan - > priority ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_LIST_INSERT_HEAD ( & traced - > trace ,  trace ,  entry ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \brief Update the context backtrace if tracing is enabled */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_trace_update ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * store  =  ast_channel_datastore_find ( chan ,  & ast_chan_trace_datastore_info ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! store ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ast_channel_trace_data_update ( chan ,  store - > data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \brief Enable context tracing in the channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_trace_enable ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * store  =  ast_channel_datastore_find ( chan ,  & ast_chan_trace_datastore_info ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_chan_trace_data  * traced ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! store )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-13 17:36:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										store  =  ast_datastore_alloc ( & ast_chan_trace_datastore_info ,  " ChanTrace " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 04:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! store )  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										traced  =  ast_calloc ( 1 ,  sizeof ( * traced ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! traced )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-13 17:36:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_datastore_free ( store ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 04:43:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										store - > data  =  traced ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_LIST_HEAD_INIT_NOLOCK ( & traced - > trace ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_datastore_add ( chan ,  store ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									( ( struct  ast_chan_trace_data  * ) store - > data ) - > enabled  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_trace_data_update ( chan ,  store - > data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \brief Disable context tracing in the channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_trace_disable ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * store  =  ast_channel_datastore_find ( chan ,  & ast_chan_trace_datastore_info ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! store ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									( ( struct  ast_chan_trace_data  * ) store - > data ) - > enabled  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif  /* CHANNEL_TRACE */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Checks to see if a channel is needing hang up */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-20 15:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_check_hangup ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > _softhangup ) 		/* yes if soft hangup flag set */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-15 04:48:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_tvzero ( chan - > whentohangup ) ) 	/* no if no hangup scheduled */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-15 04:48:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_tvdiff_ms ( chan - > whentohangup ,  ast_tvnow ( ) )  >  0 )  	/* no if hangup time has not come yet. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-15 04:48:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-18 22:31:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_debug ( 4 ,  " Hangup time has come: % "  PRIi64  " \n " ,  ast_tvdiff_ms ( chan - > whentohangup ,  ast_tvnow ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									chan - > _softhangup  | =  AST_SOFTHANGUP_TIMEOUT ; 	/* record event */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-20 15:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_check_hangup_locked ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-08-11 21:10:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-08-11 21:10:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									res  =  ast_check_hangup ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-08-11 21:10:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  ast_channel_softhangup_cb ( void  * obj ,  void  * arg ,  int  flags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * chan  =  obj ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_softhangup ( chan ,  AST_SOFTHANGUP_SHUTDOWN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_begin_shutdown ( int  hangup ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									shutting_down  =  1 ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( hangup )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ao2_callback ( channels ,  OBJ_NODATA  |  OBJ_MULTIPLE ,  ast_channel_softhangup_cb ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief returns number of active/allocated channels */ 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_active_channels ( void ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  channels  ?  ao2_container_count ( channels )  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Cancel a shutdown in progress */ 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_cancel_shutdown ( void ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									shutting_down  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Returns non-zero if Asterisk is being shut down */ 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_shutting_down ( void ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  shutting_down ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Set when to hangup channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channel_setwhentohangup_tv ( struct  ast_channel  * chan ,  struct  timeval  offset ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-20 15:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									chan - > whentohangup  =  ast_tvzero ( offset )  ?  offset  :  ast_tvadd ( offset ,  ast_tvnow ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_queue_frame ( chan ,  & ast_null_frame ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-20 15:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channel_setwhentohangup ( struct  ast_channel  * chan ,  time_t  offset ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  timeval  when  =  {  offset ,  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_setwhentohangup_tv ( chan ,  when ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Compare a offset with when to hangup channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_channel_cmpwhentohangup_tv ( struct  ast_channel  * chan ,  struct  timeval  offset ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-04 23:28:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  timeval  whentohangup ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-04 23:28:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_tvzero ( chan - > whentohangup ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ast_tvzero ( offset )  ?  0  :  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-12 13:58:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_tvzero ( offset ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-12 13:58:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									whentohangup  =  ast_tvadd ( offset ,  ast_tvnow ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-12 13:58:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_tvdiff_ms ( whentohangup ,  chan - > whentohangup ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_cmpwhentohangup ( struct  ast_channel  * chan ,  time_t  offset ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 20:23:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  timeval  when  =  {  offset ,  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ast_channel_cmpwhentohangup_tv ( chan ,  when ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-04 23:28:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Register a new telephony channel in Asterisk */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_channel_register ( const  struct  ast_channel_tech  * tech ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-03-30 22:55:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  chanlist  * chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_WRLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-03-30 22:55:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_TRAVERSE ( & backends ,  chan ,  list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! strcasecmp ( tech - > type ,  chan - > tech - > type ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Already have a handler for type '%s' \n " ,  tech - > type ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-15 01:48:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2006-04-19 06:58:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ( chan  =  ast_calloc ( 1 ,  sizeof ( * chan ) ) ) )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 06:35:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									chan - > tech  =  tech ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_INSERT_HEAD ( & backends ,  chan ,  list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_debug ( 1 ,  " Registered handler for '%s' (%s) \n " ,  chan - > tech - > type ,  chan - > tech - > description ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_verb ( 2 ,  " Registered channel type '%s' (%s) \n " ,  chan - > tech - > type ,  chan - > tech - > description ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-24 20:29:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Unregister channel driver */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channel_unregister ( const  struct  ast_channel_tech  * tech ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 05:05:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  chanlist  * chan ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_debug ( 1 ,  " Unregistering channel type '%s' \n " ,  tech - > type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_WRLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_TRAVERSE_SAFE_BEGIN ( & backends ,  chan ,  list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( chan - > tech  = =  tech )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-08 05:28:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											AST_LIST_REMOVE_CURRENT ( list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_free ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_verb ( 2 ,  " Unregistered channel type '%s' \n " ,  tech - > type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 05:05:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 	
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-08 05:28:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_LIST_TRAVERSE_SAFE_END ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-02-24 20:29:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Get handle to channel driver based on name */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								const  struct  ast_channel_tech  * ast_get_channel_tech ( const  char  * name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  chanlist  * chanls ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 05:05:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  struct  ast_channel_tech  * ret  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_RDLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_TRAVERSE ( & backends ,  chanls ,  list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 05:05:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! strcasecmp ( name ,  chanls - > tech - > type ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ret  =  chanls - > tech ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-11 05:05:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ret ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Gives the string form of a given hangup cause */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-05 17:16:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								const  char  * ast_cause2str ( int  cause ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:43:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( x  =  0 ;  x  <  ARRAY_LEN ( causes ) ;  x + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-05 17:16:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( causes [ x ] . cause  = =  cause ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  causes [ x ] . desc ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-05 17:16:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  " Unknown " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-25 20:51:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Convert a symbolic hangup cause to number */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_str2cause ( const  char  * name ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:43:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( x  =  0 ;  x  <  ARRAY_LEN ( causes ) ;  x + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! strncasecmp ( causes [ x ] . name ,  name ,  strlen ( causes [ x ] . name ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-25 20:51:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  causes [ x ] . cause ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-21 22:36:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-12-15 04:03:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Gives the string form of a given channel state.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									\ note  This  function  is  not  reentrant . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								const  char  * ast_state2str ( enum  ast_channel_state  state ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-21 22:36:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  * buf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-01-23 00:11:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									switch  ( state )  { 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_STATE_DOWN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Down " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_STATE_RESERVED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Rsrvd " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_STATE_OFFHOOK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " OffHook " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_STATE_DIALING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Dialing " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_STATE_RING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Ring " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_STATE_RINGING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Ringing " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_STATE_UP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Up " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_STATE_BUSY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Busy " ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-05 20:58:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_STATE_DIALING_OFFHOOK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Dialing Offhook " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_STATE_PRERING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Pre-ring " ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merge team/russell/ast_verbose_threadstorage
- instead of defining a free() wrapper in a bunch of files, define it as
  ast_free() in utils.h and remove the copies from all the files.
- centralize and abstract the code used for doing thread storage. The code
  lives in threadstorage.h, with one function being implemented in utils.c.
  This new API includes generic thread storage as well as special functions
  for handling thread local dynamic length string buffers.
- update ast_inet_ntoa() to use the new threadstorage API
- update ast_state2str() to use the new threadstorage API
- update ast_cli() to use the new threadstorage API
- Modify manager_event() to use thread storage. Instead of using a buffer of
  4096 characters as the workspace for building the manager event, use a thread
  local dynamic string.  Now there is no length limitation on the length of the
  body of a manager event.
- Significantly simplify the handling of ast_verbose() ...
  - Instead of using a static char buffer and a lock to make sure only one
    thread can be using ast_verbose() at a time, use a thread local dynamic
    string as the workspace for preparing the verbose message. Instead of
    locking around the entire function, the only locking done now is when the
    message has been built and is being deliviered to the list of registered
    verbose message handlers.
  - This function was doing a strdup() on every message passed to it and
    keeping a queue of the last 200 messages in memory. This has been
    completely removed. The only place this was used was that if there were
    any messages in the verbose queue when a verbose handler was registered,
    all of the messages in the queue would be fed to it.  So, I just made sure
    that the console verbose handler and the network verbose handler (for
    remote asterisk consoles) were registered before any verbose messages.
    pbx_gtkconsole and pbx_kdeconsole will now lose a few verbose messages at
    startup, but I didn't feel the performance hit of this message queue was
    worth saving the initial verbose output for these very rarely used modules.
  - I have removed the last three arguments to the verbose handlers, leaving
    only the string itself because they aren't needed anymore. For example,
    ast_verbose had some logic for telling the verbose handler to add
    a newline if the buffer was completely full. Now that the buffer can grow
    as needed, this doesn't matter anymore.
  - remove unused function, ast_verbose_dmesg() which was to dispatch the
    message queue
  - Convert the list of verbose handlers to use the linked list macros.
- add missing newline characters to a few ast_verbose() calls
- convert the list of log channels to use the linked list macros in logger.c
- fix close_logger() to close all of the files it opened for logging
- update ast_log() to use a thread local dynamic string for its workspace
  for preparing log messages instead of a buffer of size BUFSIZ (8kB on my
  system) allocated on the stack.  The dynamic string in this case is limited
  to only growing to a maximum size of BUFSIZ.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@39272 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2006-08-08 06:32:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! ( buf  =  ast_threadstorage_get ( & state2str_threadbuf ,  STATE2STR_BUFSIZE ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  " Unknown " ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-05 20:58:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										snprintf ( buf ,  STATE2STR_BUFSIZE ,  " Unknown (%d) " ,  state ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-21 22:36:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  buf ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Gives the string form of a given transfer capability */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-01 17:00:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								char  * ast_transfercapability2str ( int  transfercapability ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-23 00:11:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									switch  ( transfercapability )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-01 17:00:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_TRANS_CAP_SPEECH : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " SPEECH " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_TRANS_CAP_DIGITAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " DIGITAL " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_TRANS_CAP_RESTRICTED_DIGITAL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " RESTRICTED_DIGITAL " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_TRANS_CAP_3_1K_AUDIO : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " 3K1AUDIO " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_TRANS_CAP_DIGITAL_W_TONES : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " DIGITAL_W_TONES " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_TRANS_CAP_VIDEO : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " VIDEO " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " UNKNOWN " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-06-06 16:09:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Pick the best audio codec */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								format_t  ast_best_codec ( format_t  fmts ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* This just our opinion, expressed in code.  We are asked to choose
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									   the  best  codec  to  use ,  given  no  information  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									static  const  format_t  prefs [ ]  = 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									{ 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*! Okay, ulaw is used by all telephony equipment, so start with it */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_ULAW , 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*! Unless of course, you're a silly European, so then prefer ALAW */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_ALAW , 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-16 19:03:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_G719 , 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-24 22:00:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_SIREN14 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_FORMAT_SIREN7 , 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_TESTLAW , 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-14 01:12:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_FORMAT_G722 , 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*! Okay, well, signed linear is easy to translate into other stuff */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-17 23:20:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_SLINEAR16 , 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_SLINEAR , 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-12 22:42:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*! G.726 is standard ADPCM, in RFC3551 packing order */ 
							 
						 
					
						
							
								
									
										
										
										
											2003-11-04 02:40:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_G726 , 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-12 22:42:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*! G.726 is standard ADPCM, in AAL2 packing order */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_FORMAT_G726_AAL2 , 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*! ADPCM has great sound quality and is still pretty easy to translate */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_ADPCM , 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										    translate  and  sounds  pretty  good  */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_GSM , 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*! iLBC is not too bad */ 
							 
						 
					
						
							
								
									
										
										
										
											2003-04-15 04:36:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_ILBC , 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*! Speex is free, but computationally more expensive than GSM */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-17 17:23:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_SPEEX16 , 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_SPEEX , 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										    to  use  it  */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_LPC10 , 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*! G.729a is faster than 723 and slightly less expensive */ 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_G729A , 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*! Down to G.723.1 which is proprietary but at least designed for voice */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_FORMAT_G723_1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  buf [ 512 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-06 16:09:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Strip out video */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									fmts  & =  AST_FORMAT_AUDIO_MASK ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2006-01-16 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Find the first preferred codec in the format given */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-08 16:40:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( x  =  0 ;  x  <  ARRAY_LEN ( prefs ) ;  x + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( fmts  &  prefs [ x ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  prefs [ x ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-24 03:34:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_log ( LOG_WARNING ,  " Don't know any of %s formats \n " ,  ast_getformatname_multiple ( buf ,  sizeof ( buf ) ,  fmts ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-24 03:34:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  const  struct  ast_channel_tech  null_tech  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. type  =  " NULL " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-27 21:58:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									. description  =  " Null channel (should not see this) " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  ast_channel_destructor ( void  * obj ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  ast_dummy_channel_destructor ( void  * obj ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Create a new channel structure */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  struct  ast_channel  *  attribute_malloc  __attribute__ ( ( format ( printf ,  13 ,  0 ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 10:34:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								__ast_channel_alloc_ap ( int  needqueue ,  int  state ,  const  char  * cid_num ,  const  char  * cid_name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										       const  char  * acctcode ,  const  char  * exten ,  const  char  * context , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										       const  char  * linkedid ,  const  int  amaflag ,  const  char  * file ,  int  line , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										       const  char  * function ,  const  char  * name_fmt ,  va_list  ap1 ,  va_list  ap2 ) 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * tmp ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  flags ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  varshead  * headp ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-28 18:18:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  * tech  =  " " ,  * tech2  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* If shutting down, don't allocate any new channels */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-15 04:48:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( shutting_down )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Channel allocation failed: Refusing due to active shutdown \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-15 04:48:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 10:34:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# if defined(REF_DEBUG) 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tmp  =  __ao2_alloc_debug ( sizeof ( * tmp ) ,  ast_channel_destructor ,  " " ,  file ,  line , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										function ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 10:34:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# elif defined(__AST_DEBUG_MALLOC) 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tmp  =  __ao2_alloc_debug ( sizeof ( * tmp ) ,  ast_channel_destructor ,  " " ,  file ,  line , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										function ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 10:34:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# else 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tmp  =  ao2_alloc ( sizeof ( * tmp ) ,  ast_channel_destructor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! tmp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Channel structure allocation failure. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Init  file  descriptors  to  unopened  state  so 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  the  destructor  can  know  not  to  close  them . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									tmp - > timingfd  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( x  =  0 ;  x  <  ARRAY_LEN ( tmp - > alertpipe ) ;  + + x )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tmp - > alertpipe [ x ]  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( x  =  0 ;  x  <  ARRAY_LEN ( tmp - > fds ) ;  + + x )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tmp - > fds [ x ]  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef HAVE_EPOLL 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									tmp - > epfd  =  epoll_create ( 25 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 10:34:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-15 01:48:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ( tmp - > sched  =  sched_context_create ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-15 04:48:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Channel allocation failed: Unable to create schedule context \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-11 15:40:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  ast_channel_unref ( tmp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_dialed_init ( & tmp - > dialed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_caller_init ( & tmp - > caller ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_connected_line_init ( & tmp - > connected ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_redirecting_init ( & tmp - > redirecting ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 16:06:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( cid_name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										tmp - > caller . id . name . valid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tmp - > caller . id . name . str  =  ast_strdup ( cid_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! tmp - > caller . id . name . str )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-10 18:58:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  ast_channel_unref ( tmp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 16:06:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( cid_num )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										tmp - > caller . id . number . valid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tmp - > caller . id . number . str  =  ast_strdup ( cid_num ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! tmp - > caller . id . number . str )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-10 18:58:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  ast_channel_unref ( tmp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 16:06:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-27 19:10:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ( tmp - > timer  =  ast_timer_open ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-08 21:59:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( strcmp ( ast_timer_get_name ( tmp - > timer ) ,  " timerfd " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											needqueue  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-27 19:10:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										tmp - > timingfd  =  ast_timer_fd ( tmp - > timer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( needqueue )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( pipe ( tmp - > alertpipe ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-09 15:38:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Channel allocation failed: Can't create alert pipe! Try increasing max file descriptors with ulimit -n \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  ast_channel_unref ( tmp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											flags  =  fcntl ( tmp - > alertpipe [ 0 ] ,  F_GETFL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-12 15:14:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( fcntl ( tmp - > alertpipe [ 0 ] ,  F_SETFL ,  flags  |  O_NONBLOCK )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s) \n " ,  errno ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												return  ast_channel_unref ( tmp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-12 15:14:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											flags  =  fcntl ( tmp - > alertpipe [ 1 ] ,  F_GETFL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-12 15:14:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( fcntl ( tmp - > alertpipe [ 1 ] ,  F_SETFL ,  flags  |  O_NONBLOCK )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s) \n " ,  errno ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												return  ast_channel_unref ( tmp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-12 15:14:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  This  is  the  last  place  the  channel  constructor  can  fail . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  The  destructor  takes  advantage  of  this  fact  to  ensure  that  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  AST_CEL_CHANNEL_END  is  not  posted  if  we  have  not  posted  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  AST_CEL_CHANNEL_START  yet . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( ast_string_field_init ( tmp ,  128 ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ast_channel_unref ( tmp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Always watch the alertpipe */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_set_fd ( tmp ,  AST_ALERT_FD ,  tmp - > alertpipe [ 0 ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* And timing pipe */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_set_fd ( tmp ,  AST_TIMING_FD ,  tmp - > timingfd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-07 21:47:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Initial state */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-07 21:47:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tmp - > _state  =  state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tmp - > streamid  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 19:35:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tmp - > fin  =  global_fin ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									tmp - > fout  =  global_fout ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 19:35:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ast_strlen_zero ( ast_config_AST_SYSTEM_NAME ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_build ( tmp ,  uniqueid ,  " %li.%d " ,  ( long )  time ( NULL ) ,  
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_atomic_fetchadd_int ( & uniqueint ,  1 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 19:35:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_build ( tmp ,  uniqueid ,  " %s-%li.%d " ,  ast_config_AST_SYSTEM_NAME ,  
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											( long )  time ( NULL ) ,  ast_atomic_fetchadd_int ( & uniqueint ,  1 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 19:35:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_strlen_zero ( linkedid ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_set ( tmp ,  linkedid ,  linkedid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_string_field_set ( tmp ,  linkedid ,  tmp - > uniqueid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-11-07 21:47:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ast_strlen_zero ( name_fmt ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-28 18:18:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										char  * slash ,  * slash2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-07 21:47:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  And  they  all  use  slightly  different  formats  for  their  name  string . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  This  means ,  to  set  the  name  here ,  we  have  to  accept  variable  args ,  and  call  the  string_field_build  from  here . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  This  means ,  that  the  stringfields  must  have  a  routine  that  takes  the  va_lists  directly ,  and  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  uses  them  to  build  the  string ,  instead  of  forming  the  va_lists  internally  from  the  vararg  . . .  list . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  This  new  function  was  written  so  this  can  be  accomplished . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_build_va ( tmp ,  name ,  name_fmt ,  ap1 ,  ap2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-26 21:13:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										tech  =  ast_strdupa ( tmp - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ( slash  =  strchr ( tech ,  ' / ' ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-28 18:18:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ( slash2  =  strchr ( slash  +  1 ,  ' / ' ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												tech2  =  slash  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												* slash2  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-26 21:13:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											* slash  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  Start  the  string  with  ' - '  so  it  becomes  an  empty  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  in  the  destructor . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_set ( tmp ,  name ,  " -**Unknown** " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-07 21:47:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-30 14:37:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-30 17:57:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-10 05:41:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* These 4 variables need to be set up for the cdr_init() to work right */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( amaflag ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tmp - > amaflags  =  amaflag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tmp - > amaflags  =  ast_default_amaflags ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_strlen_zero ( acctcode ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_set ( tmp ,  accountcode ,  acctcode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_set ( tmp ,  accountcode ,  ast_default_accountcode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_strlen_zero ( context ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_copy_string ( tmp - > context ,  context ,  sizeof ( tmp - > context ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										strcpy ( tmp - > context ,  " default " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_strlen_zero ( exten ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_copy_string ( tmp - > exten ,  exten ,  sizeof ( tmp - > exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										strcpy ( tmp - > exten ,  " s " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									tmp - > priority  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-30 14:37:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tmp - > cdr  =  ast_cdr_alloc ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_cdr_init ( tmp - > cdr ,  tmp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_cdr_start ( tmp - > cdr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_cel_report_event ( tmp ,  AST_CEL_CHANNEL_START ,  NULL ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									headp  =  & tmp - > varshead ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-31 15:34:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_LIST_HEAD_INIT_NOLOCK ( headp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 19:35:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2006-04-10 23:29:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_LIST_HEAD_INIT_NOLOCK ( & tmp - > datastores ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_LIST_HEAD_INIT_NOLOCK ( & tmp - > autochans ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 19:35:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_string_field_set ( tmp ,  language ,  defaultlanguage ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									tmp - > tech  =  & null_tech ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ao2_link ( channels ,  tmp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-21 19:35:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  And  now ,  since  the  channel  structure  is  built ,  and  has  its  name ,  let ' s 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-24 19:43:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									 *  call  the  manager  event  generator  with  this  Newchannel  event .  This  is  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  proper  and  correct  place  to  make  this  call ,  but  you  sure  do  have  to  pass 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  a  lot  of  data  into  this  func  to  do  it  here ! 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-28 18:18:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_get_channel_tech ( tech )  | |  ( tech2  & &  ast_get_channel_tech ( tech2 ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_manager_event ( tmp ,  EVENT_FLAG_CALL ,  " Newchannel " , 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-24 19:43:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											" Channel: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" ChannelState: %d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" ChannelStateDesc: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" CallerIDNum: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" CallerIDName: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" AccountCode: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-26 12:32:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											" Exten: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" Context: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-24 19:43:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											" Uniqueid: %s \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											tmp - > name ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											state ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_state2str ( state ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											S_OR ( cid_num ,  " " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											S_OR ( cid_name ,  " " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											tmp - > accountcode , 
							 
						 
					
						
							
								
									
										
										
										
											2009-01-26 12:32:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											S_OR ( exten ,  " " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											S_OR ( context ,  " " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-24 19:43:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											tmp - > uniqueid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									return  tmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 10:34:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * __ast_channel_alloc ( int  needqueue ,  int  state ,  const  char  * cid_num , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													const  char  * cid_name ,  const  char  * acctcode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													const  char  * exten ,  const  char  * context , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													const  char  * linkedid ,  const  int  amaflag , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													const  char  * file ,  int  line ,  const  char  * function , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													const  char  * name_fmt ,  . . . ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 10:34:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									va_list  ap1 ,  ap2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									va_start ( ap1 ,  name_fmt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									va_start ( ap2 ,  name_fmt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									result  =  __ast_channel_alloc_ap ( needqueue ,  state ,  cid_num ,  cid_name ,  acctcode ,  exten ,  context , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													linkedid ,  amaflag ,  file ,  line ,  function ,  name_fmt ,  ap1 ,  ap2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 10:34:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									va_end ( ap1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									va_end ( ap2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* only do the minimum amount of work needed here to make a channel
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  structure  that  can  be  used  to  expand  channel  vars  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-29 17:56:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# if defined(REF_DEBUG) || defined(__AST_DEBUG_MALLOC) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_channel  * __ast_dummy_channel_alloc ( const  char  * file ,  int  line ,  const  char  * function ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# else 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_dummy_channel_alloc ( void ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-29 17:56:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * tmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  varshead  * headp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# if defined(REF_DEBUG) 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tmp  =  __ao2_alloc_debug ( sizeof ( * tmp ) ,  ast_dummy_channel_destructor ,  " dummy channel " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										file ,  line ,  function ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# elif defined(__AST_DEBUG_MALLOC) 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tmp  =  __ao2_alloc_debug ( sizeof ( * tmp ) ,  ast_dummy_channel_destructor ,  " dummy channel " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										file ,  line ,  function ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# else 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tmp  =  ao2_alloc ( sizeof ( * tmp ) ,  ast_dummy_channel_destructor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! tmp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Dummy channel structure allocation failure. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( ast_string_field_init ( tmp ,  128 ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  ast_channel_unref ( tmp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									headp  =  & tmp - > varshead ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_LIST_HEAD_INIT_NOLOCK ( headp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  tmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  __ast_queue_frame ( struct  ast_channel  * chan ,  struct  ast_frame  * fin ,  int  head ,  struct  ast_frame  * after ) 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_frame  * f ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 20:50:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_frame  * cur ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									unsigned  int  new_frames  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  new_voice_frames  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  queued_frames  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  queued_voice_frames  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_LIST_HEAD_NOLOCK ( ,  ast_frame )  frames ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 20:50:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Check  the  last  frame  on  the  queue  if  we  are  queuing  the  new 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  frames  after  it . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									cur  =  AST_LIST_LAST ( & chan - > readq ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( cur  & &  cur - > frametype  = =  AST_FRAME_CONTROL  & &  ! head  & &  ( ! after  | |  after  = =  cur ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  ( cur - > subclass . integer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONTROL_END_OF_Q : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( fin - > frametype  = =  AST_FRAME_CONTROL 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												& &  fin - > subclass . integer  = =  AST_CONTROL_HANGUP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 *  Destroy  the  end - of - Q  marker  frame  so  we  can  queue  the  hangup 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 *  frame  in  its  place . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												AST_LIST_REMOVE ( & chan - > readq ,  cur ,  frame_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_frfree ( cur ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 *  This  has  degenerated  to  a  normal  queue  append  anyway .   Since 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 *  we  just  destroyed  the  last  frame  in  the  queue  we  must  make 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 *  sure  that  " after "  is  NULL  or  bad  things  will  happen . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												after  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* Fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONTROL_HANGUP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* Don't queue anything. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 20:50:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Build copies of all the new frames and count them */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_LIST_HEAD_INIT_NOLOCK ( & frames ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( cur  =  fin ;  cur ;  cur  =  AST_LIST_NEXT ( cur ,  frame_list ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! ( f  =  ast_frdup ( cur ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-21 19:48:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( AST_LIST_FIRST ( & frames ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_frfree ( AST_LIST_FIRST ( & frames ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-25 22:33:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_LIST_INSERT_TAIL ( & frames ,  f ,  frame_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										new_frames + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( f - > frametype  = =  AST_FRAME_VOICE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											new_voice_frames + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 20:50:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Count how many frames exist on the queue */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_LIST_TRAVERSE ( & chan - > readq ,  cur ,  frame_list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										queued_frames + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( cur - > frametype  = =  AST_FRAME_VOICE )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											queued_voice_frames + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 20:50:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-01 17:53:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ( queued_frames  +  new_frames  >  128  | |  queued_voice_frames  +  new_voice_frames  >  96 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Exceptionally long %squeue length queuing to %s \n " ,  queued_frames  +  new_frames  >  128  ?  " "  :  " voice  " ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_LIST_TRAVERSE_SAFE_BEGIN ( & chan - > readq ,  cur ,  frame_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* Save the most recent frame */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ! AST_LIST_NEXT ( cur ,  frame_list ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}  else  if  ( cur - > frametype  = =  AST_FRAME_VOICE  | |  cur - > frametype  = =  AST_FRAME_VIDEO  | |  cur - > frametype  = =  AST_FRAME_NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( + + count  >  64 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												AST_LIST_REMOVE_CURRENT ( frame_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_frfree ( cur ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-01 17:53:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_LIST_TRAVERSE_SAFE_END ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( after )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_LIST_INSERT_LIST_AFTER ( & chan - > readq ,  & frames ,  after ,  frame_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( head )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											AST_LIST_APPEND_LIST ( & frames ,  & chan - > readq ,  frame_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											AST_LIST_HEAD_INIT_NOLOCK ( & chan - > readq ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_LIST_APPEND_LIST ( & chan - > readq ,  & frames ,  frame_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > alertpipe [ 1 ]  >  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-11-14 19:05:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										int  blah [ new_frames ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										memset ( blah ,  1 ,  sizeof ( blah ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( write ( chan - > alertpipe [ 1 ] ,  & blah ,  sizeof ( blah ) )  ! =  ( sizeof ( blah ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Unable to write to alert pipe on %s (qlen = %d): %s! \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												chan - > name ,  queued_frames ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2004-03-19 04:23:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  if  ( chan - > timingfd  >  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-27 19:10:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_timer_enable_continuous ( chan - > timer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  if  ( ast_test_flag ( chan ,  AST_FLAG_BLOCKING ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2003-04-11 04:31:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pthread_kill ( chan - > blocker ,  SIGURG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_queue_frame ( struct  ast_channel  * chan ,  struct  ast_frame  * fin ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  __ast_queue_frame ( chan ,  fin ,  0 ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_queue_frame_head ( struct  ast_channel  * chan ,  struct  ast_frame  * fin ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  __ast_queue_frame ( chan ,  fin ,  1 ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Queue a hangup frame for channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-22 16:29:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_queue_hangup ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_frame  f  =  {  AST_FRAME_CONTROL ,  . subclass . integer  =  AST_CONTROL_HANGUP  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-22 16:29:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Yeah, let's not change a lock-critical value without locking */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_channel_trylock ( chan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > _softhangup  | =  AST_SOFTHANGUP_DEV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ast_queue_frame ( chan ,  & f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \brief Queue a hangup frame for channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_queue_hangup_with_cause ( struct  ast_channel  * chan ,  int  cause ) 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_frame  f  =  {  AST_FRAME_CONTROL ,  . subclass . integer  =  AST_CONTROL_HANGUP  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-24 22:16:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( cause  > =  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-22 16:29:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										f . data . uint32  =  cause ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-24 22:16:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-16 18:11:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Yeah, let's not change a lock-critical value without locking */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ast_channel_trylock ( chan ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-16 18:11:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > _softhangup  | =  AST_SOFTHANGUP_DEV ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-24 22:16:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( cause  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-22 16:29:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											f . data . uint32  =  chan - > hangupcause ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-24 22:16:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-16 18:11:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-09 16:53:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-04-06 22:17:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_queue_frame ( chan ,  & f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Queue a control frame */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-09 14:25:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_queue_control ( struct  ast_channel  * chan ,  enum  ast_control_frame_type  control ) 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_frame  f  =  {  AST_FRAME_CONTROL ,  . subclass . integer  =  control  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-09 14:25:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_queue_frame ( chan ,  & f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \brief Queue a control frame with payload */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_queue_control_data ( struct  ast_channel  * chan ,  enum  ast_control_frame_type  control , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											   const  void  * data ,  size_t  datalen ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_frame  f  =  {  AST_FRAME_CONTROL ,  . subclass . integer  =  control ,  . data . ptr  =  ( void  * )  data ,  . datalen  =  datalen  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-06 22:17:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_queue_frame ( chan ,  & f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Set defer DTMF flag on channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_channel_defer_dtmf ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  pre  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan )  { 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pre  =  ast_test_flag ( chan ,  AST_FLAG_DEFER_DTMF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_set_flag ( chan ,  AST_FLAG_DEFER_DTMF ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  pre ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Unset defer DTMF flag on channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channel_undefer_dtmf ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_clear_flag ( chan ,  AST_FLAG_DEFER_DTMF ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_channel_callback ( ao2_callback_data_fn  * cb_fn ,  void  * arg , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										void  * data ,  int  ao2_flags ) 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-18 07:01:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ao2_callback_data ( channels ,  ao2_flags ,  cb_fn ,  arg ,  data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_channel_iterator  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* storage for non-dynamically allocated iterator */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ao2_iterator  simple_iterator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* pointer to the actual iterator (simple_iterator or a dynamically
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  allocated  iterator ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ao2_iterator  * active_iterator ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_channel_iterator  * ast_channel_iterator_destroy ( struct  ast_channel_iterator  * i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ao2_iterator_destroy ( i - > active_iterator ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_free ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-06 02:29:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  struct  ast_channel_iterator  * channel_iterator_search ( const  char  * name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															    size_t  name_len ,  const  char  * exten , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															    const  char  * context ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-06 02:29:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel_iterator  * i ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  tmp_chan  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name  =  name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* This is sort of a hack.  Basically, we're using an arbitrary field
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  in  ast_channel  to  pass  the  name_len  for  a  prefix  match .   If  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  gets  changed ,  then  the  compare  callback  must  be  changed ,  too .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. rings  =  name_len , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ( i  =  ast_calloc ( 1 ,  sizeof ( * i ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( exten )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_copy_string ( tmp_chan . exten ,  exten ,  sizeof ( tmp_chan . exten ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( context )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_copy_string ( tmp_chan . context ,  context ,  sizeof ( tmp_chan . context ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ( i - > active_iterator  =  ao2_find ( channels ,  & tmp_chan , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													    OBJ_MULTIPLE  |  ( ( ! ast_strlen_zero ( name )  & &  ( name_len  = =  0 ) )  ?  OBJ_POINTER  :  0 ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										    ast_free ( i ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										    return  NULL ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel_iterator  * ast_channel_iterator_by_exten_new ( const  char  * exten ,  const  char  * context ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-08 21:14:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  channel_iterator_search ( NULL ,  0 ,  exten ,  context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-16 16:11:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel_iterator  * ast_channel_iterator_by_name_new ( const  char  * name ,  size_t  name_len ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-16 16:11:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  channel_iterator_search ( name ,  name_len ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-15 16:34:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel_iterator  * ast_channel_iterator_all_new ( void ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-15 16:34:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel_iterator  * i ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ( i  =  ast_calloc ( 1 ,  sizeof ( * i ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									i - > simple_iterator  =  ao2_iterator_init ( channels ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									i - > active_iterator  =  & i - > simple_iterator ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_channel_iterator_next ( struct  ast_channel_iterator  * i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ao2_iterator_next ( i - > active_iterator ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-05-22 04:11:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 14:38:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  ast_channel_cmp_cb ( void  * obj ,  void  * arg ,  int  flags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * chan  =  obj ,  * cmp_args  =  arg ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  name_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  ret  =  CMP_MATCH ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* This is sort of a hack.  Basically, we're using an arbitrary field
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  in  ast_channel  to  pass  the  name_len  for  a  prefix  match .   If  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  gets  changed ,  then  the  uses  of  ao2_find ( )  must  be  changed ,  too .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									name_len  =  cmp_args - > rings ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 23:41:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ast_strlen_zero ( cmp_args - > name ) )  {  /* match by name */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 14:38:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ( ! name_len  & &  strcasecmp ( chan - > name ,  cmp_args - > name ) )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												( name_len  & &  strncasecmp ( chan - > name ,  cmp_args - > name ,  name_len ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ret  =  0 ;  /* name match failed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 23:41:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  if  ( ! ast_strlen_zero ( cmp_args - > exten ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 14:38:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( cmp_args - > context  & &  strcasecmp ( chan - > context ,  cmp_args - > context )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												strcasecmp ( chan - > macrocontext ,  cmp_args - > context ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ret  =  0 ;  /* context match failed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ret  & &  strcasecmp ( chan - > exten ,  cmp_args - > exten )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												strcasecmp ( chan - > macroexten ,  cmp_args - > exten ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ret  =  0 ;  /* exten match failed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 23:41:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  if  ( ! ast_strlen_zero ( cmp_args - > uniqueid ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 14:38:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ( ! name_len  & &  strcasecmp ( chan - > uniqueid ,  cmp_args - > uniqueid ) )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												( name_len  & &  strncasecmp ( chan - > uniqueid ,  cmp_args - > uniqueid ,  name_len ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ret  =  0 ;  /* uniqueid match failed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-12-15 23:41:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ret  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 14:38:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  struct  ast_channel  * ast_channel_get_full ( const  char  * name ,  size_t  name_len , 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-21 21:08:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														const  char  * exten ,  const  char  * context ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-28 23:36:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  tmp_chan  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name  =  name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* This is sort of a hack.  Basically, we're using an arbitrary field
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  in  ast_channel  to  pass  the  name_len  for  a  prefix  match .   If  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  gets  changed ,  then  the  compare  callback  must  be  changed ,  too .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. rings  =  name_len , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-10 15:46:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * chan ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( exten )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_copy_string ( tmp_chan . exten ,  exten ,  sizeof ( tmp_chan . exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( context )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_copy_string ( tmp_chan . context ,  context ,  sizeof ( tmp_chan . context ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 14:38:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ( chan  =  ao2_find ( channels ,  & tmp_chan , 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-25 14:44:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											     ( ! ast_strlen_zero ( name )  & &  ( name_len  = =  0 ) )  ?  OBJ_POINTER  :  0 ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-10 15:46:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* If name was specified, but the result was NULL, 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  try  a  search  on  uniqueid ,  instead .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										struct  ast_channel  tmp_chan2  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											. uniqueid  =  name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											. rings  =  name_len , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ao2_find ( channels ,  & tmp_chan2 ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-28 23:36:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_channel_get_by_name ( const  char  * name ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-04 23:23:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_channel_get_full ( name ,  0 ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-04 23:23:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_channel_get_by_name_prefix ( const  char  * name ,  size_t  name_len ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ast_channel_get_full ( name ,  name_len ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-04 23:23:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_channel_get_by_exten ( const  char  * exten ,  const  char  * context ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ast_channel_get_full ( NULL ,  0 ,  exten ,  context ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-04 23:23:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 264996 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
  r264996 | mmichelson | 2010-05-21 11:28:34 -0500 (Fri, 21 May 2010) | 32 lines
  
  Allow ast_safe_sleep to defer specific frames until after the sleep has concluded.
  
  From reviewboard
  
  Background:
  A Digium customer discovered a somewhat odd bug. The setup is that parties A
  and B are bridged, and party A places party B on hold. While party B is 
  listening to hold music, he mashes a bunch of DTMF. Party A takes party
  B off hold while this is happening, but party B continues to hear hold
  music. I could reproduce this about 1 in 5 times.
  
  The issue:
  When DTMF features are enabled and a user presses keys, the channel that
  the DTMF is streamed to is placed in an ast_safe_sleep for 100 ms, the
  duration of the emulated tone. If an AST_CONTROL_UNHOLD frame is read
  from the channel during the sleep, the frame is dropped. Thus the
  unhold indication is never made to the channel that was originally placed
  on hold.
  
  The fix:
  Originally, I discussed with Kevin possible ways of fixing the specific
  problem reported. However, we determined that the same type of problem
  could happen in other situations where ast_safe_sleep() is used. Using
  autoservice as a model, I modified ast_safe_sleep_conditional() to
  defer specific frame types so they can be re-queued once the sleep has
  finished. I made a common function for determining if a frame should
  be deferred so that there are not two identical switch blocks to
  maintain.
  
  Review: https://reviewboard.asterisk.org/r/674/
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264997 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-21 16:44:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_is_deferrable_frame ( const  struct  ast_frame  * frame ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Do not add a default entry in this switch statement.  Each new
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  frame  type  should  be  addressed  directly  as  to  whether  it  should 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  be  queued  up  or  not . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( frame - > frametype )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_CONTROL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_TEXT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_IMAGE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_HTML : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-12 18:12:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_FRAME_DTMF_END : 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 264996 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
  r264996 | mmichelson | 2010-05-21 11:28:34 -0500 (Fri, 21 May 2010) | 32 lines
  
  Allow ast_safe_sleep to defer specific frames until after the sleep has concluded.
  
  From reviewboard
  
  Background:
  A Digium customer discovered a somewhat odd bug. The setup is that parties A
  and B are bridged, and party A places party B on hold. While party B is 
  listening to hold music, he mashes a bunch of DTMF. Party A takes party
  B off hold while this is happening, but party B continues to hear hold
  music. I could reproduce this about 1 in 5 times.
  
  The issue:
  When DTMF features are enabled and a user presses keys, the channel that
  the DTMF is streamed to is placed in an ast_safe_sleep for 100 ms, the
  duration of the emulated tone. If an AST_CONTROL_UNHOLD frame is read
  from the channel during the sleep, the frame is dropped. Thus the
  unhold indication is never made to the channel that was originally placed
  on hold.
  
  The fix:
  Originally, I discussed with Kevin possible ways of fixing the specific
  problem reported. However, we determined that the same type of problem
  could happen in other situations where ast_safe_sleep() is used. Using
  autoservice as a model, I modified ast_safe_sleep_conditional() to
  defer specific frame types so they can be re-queued once the sleep has
  finished. I made a common function for determining if a frame should
  be deferred so that there are not two identical switch blocks to
  maintain.
  
  Review: https://reviewboard.asterisk.org/r/674/
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264997 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-21 16:44:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_FRAME_DTMF_BEGIN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_VOICE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_VIDEO : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_NULL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_IAX : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_CNG : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_MODEM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Wait, look for hangups and condition arg */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-01 08:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_safe_sleep_conditional ( struct  ast_channel  * chan ,  int  ms ,  int  ( * cond ) ( void * ) ,  void  * data ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_frame  * f ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-13 16:31:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_silence_generator  * silgen  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 264996 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
  r264996 | mmichelson | 2010-05-21 11:28:34 -0500 (Fri, 21 May 2010) | 32 lines
  
  Allow ast_safe_sleep to defer specific frames until after the sleep has concluded.
  
  From reviewboard
  
  Background:
  A Digium customer discovered a somewhat odd bug. The setup is that parties A
  and B are bridged, and party A places party B on hold. While party B is 
  listening to hold music, he mashes a bunch of DTMF. Party A takes party
  B off hold while this is happening, but party B continues to hear hold
  music. I could reproduce this about 1 in 5 times.
  
  The issue:
  When DTMF features are enabled and a user presses keys, the channel that
  the DTMF is streamed to is placed in an ast_safe_sleep for 100 ms, the
  duration of the emulated tone. If an AST_CONTROL_UNHOLD frame is read
  from the channel during the sleep, the frame is dropped. Thus the
  unhold indication is never made to the channel that was originally placed
  on hold.
  
  The fix:
  Originally, I discussed with Kevin possible ways of fixing the specific
  problem reported. However, we determined that the same type of problem
  could happen in other situations where ast_safe_sleep() is used. Using
  autoservice as a model, I modified ast_safe_sleep_conditional() to
  defer specific frame types so they can be re-queued once the sleep has
  finished. I made a common function for determining if a frame should
  be deferred so that there are not two identical switch blocks to
  maintain.
  
  Review: https://reviewboard.asterisk.org/r/674/
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264997 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-21 16:44:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_LIST_HEAD_NOLOCK ( ,  ast_frame )  deferred_frames ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_LIST_HEAD_INIT_NOLOCK ( & deferred_frames ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-13 16:31:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* If no other generator is present, start silencegen while waiting */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ast_opt_transmit_silence  & &  ! chan - > generatordata )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										silgen  =  ast_channel_start_silence_generator ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-01 08:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									while  ( ms  >  0 )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 264996 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
  r264996 | mmichelson | 2010-05-21 11:28:34 -0500 (Fri, 21 May 2010) | 32 lines
  
  Allow ast_safe_sleep to defer specific frames until after the sleep has concluded.
  
  From reviewboard
  
  Background:
  A Digium customer discovered a somewhat odd bug. The setup is that parties A
  and B are bridged, and party A places party B on hold. While party B is 
  listening to hold music, he mashes a bunch of DTMF. Party A takes party
  B off hold while this is happening, but party B continues to hear hold
  music. I could reproduce this about 1 in 5 times.
  
  The issue:
  When DTMF features are enabled and a user presses keys, the channel that
  the DTMF is streamed to is placed in an ast_safe_sleep for 100 ms, the
  duration of the emulated tone. If an AST_CONTROL_UNHOLD frame is read
  from the channel during the sleep, the frame is dropped. Thus the
  unhold indication is never made to the channel that was originally placed
  on hold.
  
  The fix:
  Originally, I discussed with Kevin possible ways of fixing the specific
  problem reported. However, we determined that the same type of problem
  could happen in other situations where ast_safe_sleep() is used. Using
  autoservice as a model, I modified ast_safe_sleep_conditional() to
  defer specific frame types so they can be re-queued once the sleep has
  finished. I made a common function for determining if a frame should
  be deferred so that there are not two identical switch blocks to
  maintain.
  
  Review: https://reviewboard.asterisk.org/r/674/
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264997 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-21 16:44:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										struct  ast_frame  * dup_f  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-13 16:31:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( cond  & &  ( ( * cond ) ( data )  = =  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ms  =  ast_waitfor ( chan ,  ms ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-13 16:31:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ms  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ms  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											f  =  ast_read ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-13 16:31:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ! f )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 264996 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
  r264996 | mmichelson | 2010-05-21 11:28:34 -0500 (Fri, 21 May 2010) | 32 lines
  
  Allow ast_safe_sleep to defer specific frames until after the sleep has concluded.
  
  From reviewboard
  
  Background:
  A Digium customer discovered a somewhat odd bug. The setup is that parties A
  and B are bridged, and party A places party B on hold. While party B is 
  listening to hold music, he mashes a bunch of DTMF. Party A takes party
  B off hold while this is happening, but party B continues to hear hold
  music. I could reproduce this about 1 in 5 times.
  
  The issue:
  When DTMF features are enabled and a user presses keys, the channel that
  the DTMF is streamed to is placed in an ast_safe_sleep for 100 ms, the
  duration of the emulated tone. If an AST_CONTROL_UNHOLD frame is read
  from the channel during the sleep, the frame is dropped. Thus the
  unhold indication is never made to the channel that was originally placed
  on hold.
  
  The fix:
  Originally, I discussed with Kevin possible ways of fixing the specific
  problem reported. However, we determined that the same type of problem
  could happen in other situations where ast_safe_sleep() is used. Using
  autoservice as a model, I modified ast_safe_sleep_conditional() to
  defer specific frame types so they can be re-queued once the sleep has
  finished. I made a common function for determining if a frame should
  be deferred so that there are not two identical switch blocks to
  maintain.
  
  Review: https://reviewboard.asterisk.org/r/674/
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264997 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-21 16:44:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ! ast_is_deferrable_frame ( f ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ( dup_f  =  ast_frisolate ( f ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( dup_f  ! =  f )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												AST_LIST_INSERT_HEAD ( & deferred_frames ,  dup_f ,  frame_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-13 16:31:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* stop silgen if present */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( silgen )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_stop_silence_generator ( chan ,  silgen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 264996 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
  r264996 | mmichelson | 2010-05-21 11:28:34 -0500 (Fri, 21 May 2010) | 32 lines
  
  Allow ast_safe_sleep to defer specific frames until after the sleep has concluded.
  
  From reviewboard
  
  Background:
  A Digium customer discovered a somewhat odd bug. The setup is that parties A
  and B are bridged, and party A places party B on hold. While party B is 
  listening to hold music, he mashes a bunch of DTMF. Party A takes party
  B off hold while this is happening, but party B continues to hear hold
  music. I could reproduce this about 1 in 5 times.
  
  The issue:
  When DTMF features are enabled and a user presses keys, the channel that
  the DTMF is streamed to is placed in an ast_safe_sleep for 100 ms, the
  duration of the emulated tone. If an AST_CONTROL_UNHOLD frame is read
  from the channel during the sleep, the frame is dropped. Thus the
  unhold indication is never made to the channel that was originally placed
  on hold.
  
  The fix:
  Originally, I discussed with Kevin possible ways of fixing the specific
  problem reported. However, we determined that the same type of problem
  could happen in other situations where ast_safe_sleep() is used. Using
  autoservice as a model, I modified ast_safe_sleep_conditional() to
  defer specific frame types so they can be re-queued once the sleep has
  finished. I made a common function for determining if a frame should
  be deferred so that there are not two identical switch blocks to
  maintain.
  
  Review: https://reviewboard.asterisk.org/r/674/
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264997 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-21 16:44:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* We need to free all the deferred frames, but we only need to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  queue  the  deferred  frames  if  there  was  no  error  and  no 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  hangup  was  received 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									while  ( ( f  =  AST_LIST_REMOVE_HEAD ( & deferred_frames ,  frame_list ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_queue_frame_head ( chan ,  f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-13 16:31:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Wait, look for hangups */ 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_safe_sleep ( struct  ast_channel  * chan ,  int  ms ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-01 08:45:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_safe_sleep_conditional ( chan ,  ms ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_channel_release ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Safe, even if already unlinked. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ao2_unlink ( channels ,  chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ast_channel_unref ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_name_init ( struct  ast_party_name  * init ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > str  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > char_set  =  AST_PARTY_CHAR_SET_ISO8859_1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > presentation  =  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > valid  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_name_copy ( struct  ast_party_name  * dest ,  const  struct  ast_party_name  * src ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( dest  = =  src )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't copy to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_free ( dest - > str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > str  =  ast_strdup ( src - > str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > char_set  =  src - > char_set ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > presentation  =  src - > presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > valid  =  src - > valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_name_set_init ( struct  ast_party_name  * init ,  const  struct  ast_party_name  * guide ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > str  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > char_set  =  guide - > char_set ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > presentation  =  guide - > presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > valid  =  guide - > valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_name_set ( struct  ast_party_name  * dest ,  const  struct  ast_party_name  * src ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( dest  = =  src )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't set to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( src - > str  & &  src - > str  ! =  dest - > str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_free ( dest - > str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										dest - > str  =  ast_strdup ( src - > str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > char_set  =  src - > char_set ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > presentation  =  src - > presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > valid  =  src - > valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_name_free ( struct  ast_party_name  * doomed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_free ( doomed - > str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									doomed - > str  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_number_init ( struct  ast_party_number  * init ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > str  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > plan  =  0 ; /* Unknown */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > presentation  =  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > valid  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_number_copy ( struct  ast_party_number  * dest ,  const  struct  ast_party_number  * src ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( dest  = =  src )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't copy to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_free ( dest - > str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > str  =  ast_strdup ( src - > str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > plan  =  src - > plan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > presentation  =  src - > presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > valid  =  src - > valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_number_set_init ( struct  ast_party_number  * init ,  const  struct  ast_party_number  * guide ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > str  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > plan  =  guide - > plan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > presentation  =  guide - > presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > valid  =  guide - > valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_number_set ( struct  ast_party_number  * dest ,  const  struct  ast_party_number  * src ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( dest  = =  src )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't set to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( src - > str  & &  src - > str  ! =  dest - > str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_free ( dest - > str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										dest - > str  =  ast_strdup ( src - > str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > plan  =  src - > plan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > presentation  =  src - > presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > valid  =  src - > valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_number_free ( struct  ast_party_number  * doomed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_free ( doomed - > str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									doomed - > str  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_subaddress_init ( struct  ast_party_subaddress  * init ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > str  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > type  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > odd_even_indicator  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > valid  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_subaddress_copy ( struct  ast_party_subaddress  * dest ,  const  struct  ast_party_subaddress  * src ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( dest  = =  src )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't copy to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_free ( dest - > str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									dest - > str  =  ast_strdup ( src - > str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > type  =  src - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > odd_even_indicator  =  src - > odd_even_indicator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > valid  =  src - > valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_subaddress_set_init ( struct  ast_party_subaddress  * init ,  const  struct  ast_party_subaddress  * guide ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > str  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > type  =  guide - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > odd_even_indicator  =  guide - > odd_even_indicator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > valid  =  guide - > valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_subaddress_set ( struct  ast_party_subaddress  * dest ,  const  struct  ast_party_subaddress  * src ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( dest  = =  src )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't set to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( src - > str  & &  src - > str  ! =  dest - > str )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_free ( dest - > str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										dest - > str  =  ast_strdup ( src - > str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > type  =  src - > type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > odd_even_indicator  =  src - > odd_even_indicator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > valid  =  src - > valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_subaddress_free ( struct  ast_party_subaddress  * doomed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_free ( doomed - > str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									doomed - > str  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-02 22:28:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_id_init ( struct  ast_party_id  * init ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_name_init ( & init - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_number_init ( & init - > number ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_subaddress_init ( & init - > subaddress ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									init - > tag  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_id_copy ( struct  ast_party_id  * dest ,  const  struct  ast_party_id  * src ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( dest  = =  src )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't copy to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_name_copy ( & dest - > name ,  & src - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_number_copy ( & dest - > number ,  & src - > number ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_subaddress_copy ( & dest - > subaddress ,  & src - > subaddress ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_free ( dest - > tag ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									dest - > tag  =  ast_strdup ( src - > tag ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_id_set_init ( struct  ast_party_id  * init ,  const  struct  ast_party_id  * guide ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_name_set_init ( & init - > name ,  & guide - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_number_set_init ( & init - > number ,  & guide - > number ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_subaddress_set_init ( & init - > subaddress ,  & guide - > subaddress ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									init - > tag  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_id_set ( struct  ast_party_id  * dest ,  const  struct  ast_party_id  * src ,  const  struct  ast_set_party_id  * update ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( dest  = =  src )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't set to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! update  | |  update - > name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_party_name_set ( & dest - > name ,  & src - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! update  | |  update - > number )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_party_number_set ( & dest - > number ,  & src - > number ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! update  | |  update - > subaddress )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_party_subaddress_set ( & dest - > subaddress ,  & src - > subaddress ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( src - > tag  & &  src - > tag  ! =  dest - > tag )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_free ( dest - > tag ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										dest - > tag  =  ast_strdup ( src - > tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-02 22:28:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_id_free ( struct  ast_party_id  * doomed ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_name_free ( & doomed - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_number_free ( & doomed - > number ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_subaddress_free ( & doomed - > subaddress ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_free ( doomed - > tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									doomed - > tag  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_party_id_presentation ( const  struct  ast_party_id  * id ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  number_priority ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  number_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  number_screening ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  name_priority ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  name_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Determine name presentation priority. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! id - > name . valid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										name_value  =  AST_PRES_UNAVAILABLE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										name_priority  =  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										name_value  =  id - > name . presentation  &  AST_PRES_RESTRICTION ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  ( name_value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_PRES_RESTRICTED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											name_priority  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_PRES_ALLOWED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											name_priority  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_PRES_UNAVAILABLE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											name_priority  =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											name_value  =  AST_PRES_UNAVAILABLE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											name_priority  =  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Determine number presentation priority. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! id - > number . valid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										number_screening  =  AST_PRES_USER_NUMBER_UNSCREENED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										number_value  =  AST_PRES_UNAVAILABLE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										number_priority  =  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										number_screening  =  id - > number . presentation  &  AST_PRES_NUMBER_TYPE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										number_value  =  id - > number . presentation  &  AST_PRES_RESTRICTION ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  ( number_value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_PRES_RESTRICTED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											number_priority  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_PRES_ALLOWED : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											number_priority  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_PRES_UNAVAILABLE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											number_priority  =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											number_screening  =  AST_PRES_USER_NUMBER_UNSCREENED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											number_value  =  AST_PRES_UNAVAILABLE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											number_priority  =  3 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Select the wining presentation value. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( name_priority  <  number_priority )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										number_value  =  name_value ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  number_value  |  number_screening ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_dialed_init ( struct  ast_party_dialed  * init ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-04 16:36:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									init - > number . str  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > number . plan  =  0 ; /* Unknown */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_subaddress_init ( & init - > subaddress ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > transit_network_select  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-04 16:36:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_dialed_copy ( struct  ast_party_dialed  * dest ,  const  struct  ast_party_dialed  * src ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( dest  = =  src )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't copy to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_free ( dest - > number . str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > number . str  =  ast_strdup ( src - > number . str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > number . plan  =  src - > number . plan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_subaddress_copy ( & dest - > subaddress ,  & src - > subaddress ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > transit_network_select  =  src - > transit_network_select ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_dialed_set_init ( struct  ast_party_dialed  * init ,  const  struct  ast_party_dialed  * guide ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > number . str  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > number . plan  =  guide - > number . plan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_subaddress_set_init ( & init - > subaddress ,  & guide - > subaddress ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > transit_network_select  =  guide - > transit_network_select ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_dialed_set ( struct  ast_party_dialed  * dest ,  const  struct  ast_party_dialed  * src ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( src - > number . str  & &  src - > number . str  ! =  dest - > number . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_free ( dest - > number . str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										dest - > number . str  =  ast_strdup ( src - > number . str ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									dest - > number . plan  =  src - > number . plan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_subaddress_set ( & dest - > subaddress ,  & src - > subaddress ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									dest - > transit_network_select  =  src - > transit_network_select ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_dialed_free ( struct  ast_party_dialed  * doomed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_free ( doomed - > number . str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									doomed - > number . str  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_subaddress_free ( & doomed - > subaddress ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_caller_init ( struct  ast_party_caller  * init ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_init ( & init - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 16:58:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_init ( & init - > ani ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									init - > ani2  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_caller_copy ( struct  ast_party_caller  * dest ,  const  struct  ast_party_caller  * src ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( dest  = =  src )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't copy to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_copy ( & dest - > id ,  & src - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 16:58:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_copy ( & dest - > ani ,  & src - > ani ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									dest - > ani2  =  src - > ani2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_caller_set_init ( struct  ast_party_caller  * init ,  const  struct  ast_party_caller  * guide ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_set_init ( & init - > id ,  & guide - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 16:58:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_set_init ( & init - > ani ,  & guide - > ani ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									init - > ani2  =  guide - > ani2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_caller_set ( struct  ast_party_caller  * dest ,  const  struct  ast_party_caller  * src ,  const  struct  ast_set_party_caller  * update ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_set ( & dest - > id ,  & src - > id ,  update  ?  & update - > id  :  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 16:58:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_set ( & dest - > ani ,  & src - > ani ,  update  ?  & update - > ani  :  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									dest - > ani2  =  src - > ani2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_caller_free ( struct  ast_party_caller  * doomed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_free ( & doomed - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 16:58:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_free ( & doomed - > ani ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_connected_line_init ( struct  ast_party_connected_line  * init ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_init ( & init - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 16:58:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_init ( & init - > ani ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									init - > ani2  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > source  =  AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_connected_line_copy ( struct  ast_party_connected_line  * dest ,  const  struct  ast_party_connected_line  * src ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( dest  = =  src )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't copy to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_copy ( & dest - > id ,  & src - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 16:58:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_copy ( & dest - > ani ,  & src - > ani ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									dest - > ani2  =  src - > ani2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > source  =  src - > source ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_connected_line_set_init ( struct  ast_party_connected_line  * init ,  const  struct  ast_party_connected_line  * guide ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_set_init ( & init - > id ,  & guide - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 16:58:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_set_init ( & init - > ani ,  & guide - > ani ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									init - > ani2  =  guide - > ani2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > source  =  guide - > source ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_connected_line_set ( struct  ast_party_connected_line  * dest ,  const  struct  ast_party_connected_line  * src ,  const  struct  ast_set_party_connected_line  * update ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_set ( & dest - > id ,  & src - > id ,  update  ?  & update - > id  :  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 16:58:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_set ( & dest - > ani ,  & src - > ani ,  update  ?  & update - > ani  :  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									dest - > ani2  =  src - > ani2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > source  =  src - > source ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_connected_line_collect_caller ( struct  ast_party_connected_line  * connected ,  struct  ast_party_caller  * caller ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									connected - > id  =  caller - > id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									connected - > ani  =  caller - > ani ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									connected - > ani2  =  caller - > ani2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									connected - > source  =  AST_CONNECTED_LINE_UPDATE_SOURCE_UNKNOWN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_connected_line_free ( struct  ast_party_connected_line  * doomed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_free ( & doomed - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 16:58:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_free ( & doomed - > ani ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_redirecting_init ( struct  ast_party_redirecting  * init ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_init ( & init - > from ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_init ( & init - > to ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > reason  =  AST_REDIRECTING_REASON_UNKNOWN ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_redirecting_copy ( struct  ast_party_redirecting  * dest ,  const  struct  ast_party_redirecting  * src ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( dest  = =  src )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't copy to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_copy ( & dest - > from ,  & src - > from ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_copy ( & dest - > to ,  & src - > to ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > count  =  src - > count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > reason  =  src - > reason ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_party_redirecting_set_init ( struct  ast_party_redirecting  * init ,  const  struct  ast_party_redirecting  * guide ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_set_init ( & init - > from ,  & guide - > from ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_set_init ( & init - > to ,  & guide - > to ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > count  =  guide - > count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									init - > reason  =  guide - > reason ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_redirecting_set ( struct  ast_party_redirecting  * dest ,  const  struct  ast_party_redirecting  * src ,  const  struct  ast_set_party_redirecting  * update ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_set ( & dest - > from ,  & src - > from ,  update  ?  & update - > from  :  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_set ( & dest - > to ,  & src - > to ,  update  ?  & update - > to  :  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > reason  =  src - > reason ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > count  =  src - > count ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_party_redirecting_free ( struct  ast_party_redirecting  * doomed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_free ( & doomed - > from ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_free ( & doomed - > to ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Free a channel structure */ 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  ast_channel_destructor ( void  * obj ) 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-18 07:01:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * chan  =  obj ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  fd ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef HAVE_EPOLL 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_var_t  * vardata ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 20:50:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_frame  * f ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  varshead  * headp ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-14 21:30:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * datastore ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  device_name [ AST_CHANNEL_NAME ] ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* The string fields were initialized. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_cel_report_event ( chan ,  AST_CEL_CHANNEL_END ,  NULL ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_cel_check_retire_linkedid ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-14 21:30:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Get rid of each of the data stores on the channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									while  ( ( datastore  =  AST_LIST_REMOVE_HEAD ( & chan - > datastores ,  entry ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Free the data store */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_datastore_free ( datastore ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Lock and unlock the channel just to be sure nobody has it locked still
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									   due  to  a  reference  that  was  stored  in  a  datastore .  ( i . e .  app_chanspy )  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > tech_pvt )  { 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-18 07:01:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Channel '%s' may not have been hung up properly \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_free ( chan - > tech_pvt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2003-03-30 22:55:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 7265-7266,7268-7275 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2
........
r7265 | oej | 2005-12-01 17:18:14 -0600 (Thu, 01 Dec 2005) | 2 lines
Changing bug report address to the Asterisk issue tracker
........
r7266 | kpfleming | 2005-12-01 17:18:29 -0600 (Thu, 01 Dec 2005) | 3 lines
Makefile 'update' target now supports updating from Subversion repositories (issue #5875)
remove support for 'patches' subdirectory, it's no longer useful
........
r7268 | kpfleming | 2005-12-01 17:34:58 -0600 (Thu, 01 Dec 2005) | 2 lines
ensure channel's scheduling context is freed (issue #5788)
........
r7269 | kpfleming | 2005-12-01 17:49:44 -0600 (Thu, 01 Dec 2005) | 2 lines
don't block waiting for the Festival server forever when it goes away (issue #5882)
........
r7270 | kpfleming | 2005-12-01 18:26:12 -0600 (Thu, 01 Dec 2005) | 2 lines
allow variables to exist on both 'halves' of the Local channel (issue #5810)
........
r7271 | kpfleming | 2005-12-01 18:28:48 -0600 (Thu, 01 Dec 2005) | 2 lines
protect agent_bridgedchannel() from segfaulting when there is no bridged channel (issue #5879)
........
r7272 | kpfleming | 2005-12-01 18:39:00 -0600 (Thu, 01 Dec 2005) | 3 lines
properly handle password changes when mailbox is last line of config file and not followed by a newline (issue #5870)
reformat password changing code to conform to coding guidelines (issue #5870)
........
r7273 | kpfleming | 2005-12-01 18:42:40 -0600 (Thu, 01 Dec 2005) | 2 lines
allow previous context-searching behavior to be used if desired (issue #5899)
........
r7274 | kpfleming | 2005-12-01 18:51:15 -0600 (Thu, 01 Dec 2005) | 2 lines
inherit channel variables into channels created by Page() application (issue #5888)
........
r7275 | oej | 2005-12-01 18:52:13 -0600 (Thu, 01 Dec 2005) | 2 lines
Bug #5907. Improve SIP INFO DTMF debugging output. (1.2 & Trunk)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7276 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2005-12-02 01:01:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > sched ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sched_context_destroy ( chan - > sched ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										char  * dashptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* The string fields were initialized. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_copy_string ( device_name ,  chan - > name ,  sizeof ( device_name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ( dashptr  =  strrchr ( device_name ,  ' - ' ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* dashptr  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										device_name [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-25 17:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 7265-7266,7268-7275 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2
........
r7265 | oej | 2005-12-01 17:18:14 -0600 (Thu, 01 Dec 2005) | 2 lines
Changing bug report address to the Asterisk issue tracker
........
r7266 | kpfleming | 2005-12-01 17:18:29 -0600 (Thu, 01 Dec 2005) | 3 lines
Makefile 'update' target now supports updating from Subversion repositories (issue #5875)
remove support for 'patches' subdirectory, it's no longer useful
........
r7268 | kpfleming | 2005-12-01 17:34:58 -0600 (Thu, 01 Dec 2005) | 2 lines
ensure channel's scheduling context is freed (issue #5788)
........
r7269 | kpfleming | 2005-12-01 17:49:44 -0600 (Thu, 01 Dec 2005) | 2 lines
don't block waiting for the Festival server forever when it goes away (issue #5882)
........
r7270 | kpfleming | 2005-12-01 18:26:12 -0600 (Thu, 01 Dec 2005) | 2 lines
allow variables to exist on both 'halves' of the Local channel (issue #5810)
........
r7271 | kpfleming | 2005-12-01 18:28:48 -0600 (Thu, 01 Dec 2005) | 2 lines
protect agent_bridgedchannel() from segfaulting when there is no bridged channel (issue #5879)
........
r7272 | kpfleming | 2005-12-01 18:39:00 -0600 (Thu, 01 Dec 2005) | 3 lines
properly handle password changes when mailbox is last line of config file and not followed by a newline (issue #5870)
reformat password changing code to conform to coding guidelines (issue #5870)
........
r7273 | kpfleming | 2005-12-01 18:42:40 -0600 (Thu, 01 Dec 2005) | 2 lines
allow previous context-searching behavior to be used if desired (issue #5899)
........
r7274 | kpfleming | 2005-12-01 18:51:15 -0600 (Thu, 01 Dec 2005) | 2 lines
inherit channel variables into channels created by Page() application (issue #5888)
........
r7275 | oej | 2005-12-01 18:52:13 -0600 (Thu, 01 Dec 2005) | 2 lines
Bug #5907. Improve SIP INFO DTMF debugging output. (1.2 & Trunk)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7276 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2005-12-02 01:01:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-03-25 19:30:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Stop monitoring */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-28 18:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > monitor ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-03-25 19:30:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > monitor - > stop (  chan ,  0  ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-03-30 22:55:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-12-24 01:40:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* If there is native format music-on-hold state, free it */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-28 18:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > music_state ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-24 01:40:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_moh_cleanup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-16 17:37:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Free translators */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > readtrans ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_translator_free_path ( chan - > readtrans ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan - > writetrans ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_translator_free_path ( chan - > writetrans ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > pbx ) 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-18 07:01:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " PBX may not have been terminated properly on '%s' \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_dialed_free ( & chan - > dialed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_caller_free ( & chan - > caller ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_connected_line_free ( & chan - > connected ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_redirecting_free ( & chan - > redirecting ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Close pipes if appropriate */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ( fd  =  chan - > alertpipe [ 0 ] )  >  - 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										close ( fd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ( fd  =  chan - > alertpipe [ 1 ] )  >  - 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										close ( fd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-27 19:10:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > timer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_timer_close ( chan - > timer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef HAVE_EPOLL 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( i  =  0 ;  i  <  AST_MAX_FDS ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( chan - > epfd_data [ i ] ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											free ( chan - > epfd_data [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									close ( chan - > epfd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 20:50:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									while  ( ( f  =  AST_LIST_REMOVE_HEAD ( & chan - > readq ,  frame_list ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* loop over the variables list, freeing all data and deleting list items */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* no need to lock the list, as the channel is already locked */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									headp  =  & chan - > varshead ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-28 23:01:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									while  ( ( vardata  =  AST_LIST_REMOVE_HEAD ( headp ,  entries ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_var_delete ( vardata ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-04-26 03:24:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_app_group_discard ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-31 16:56:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Destroy the jitterbuffer */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-23 16:49:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_jb_destroy ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-02 22:50:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan - > cdr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-05 14:18:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_cdr_discard ( chan - > cdr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-02 22:50:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > cdr  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 20:41:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan - > zone )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > zone  =  ast_tone_zone_unref ( chan - > zone ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-04 19:44:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_string_field_free_memory ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-03-30 22:55:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-05-21 22:46:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( device_name [ 0 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  We  have  a  device  name  to  notify  of  a  new  state . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  Queue  an  unknown  state ,  because ,  while  we  know  that  this  particular 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  instance  is  dead ,  we  don ' t  know  the  state  of  all  other  possible 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  instances . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_devstate_changed_literal ( AST_DEVICE_UNKNOWN ,  device_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-18 07:01:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Free a dummy channel structure */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  ast_dummy_channel_destructor ( void  * obj ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * chan  =  obj ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_var_t  * vardata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  varshead  * headp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									headp  =  & chan - > varshead ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_dialed_free ( & chan - > dialed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_caller_free ( & chan - > caller ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_connected_line_free ( & chan - > connected ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_redirecting_free ( & chan - > redirecting ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* loop over the variables list, freeing all data and deleting list items */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* no need to lock the list, as the channel is already locked */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									while  ( ( vardata  =  AST_LIST_REMOVE_HEAD ( headp ,  entries ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_var_delete ( vardata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan - > cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_cdr_discard ( chan - > cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > cdr  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_string_field_free_memory ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-28 18:32:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_datastore  * ast_channel_datastore_alloc ( const  struct  ast_datastore_info  * info ,  const  char  * uid ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-10 23:29:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-05 16:56:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_datastore_alloc ( info ,  uid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-10 23:29:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_datastore_free ( struct  ast_datastore  * datastore ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-05 16:56:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_datastore_free ( datastore ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-10 23:29:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-03 14:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_channel_datastore_inherit ( struct  ast_channel  * from ,  struct  ast_channel  * to ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * datastore  =  NULL ,  * datastore2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_LIST_TRAVERSE ( & from - > datastores ,  datastore ,  entry )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( datastore - > inheritance  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-05 16:56:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											datastore2  =  ast_datastore_alloc ( datastore - > info ,  datastore - > uid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-03 14:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( datastore2 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-23 15:17:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												datastore2 - > data  =  datastore - > info - > duplicate  ?  datastore - > info - > duplicate ( datastore - > data )  :  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-03 14:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												datastore2 - > inheritance  =  datastore - > inheritance  = =  DATASTORE_INHERIT_FOREVER  ?  DATASTORE_INHERIT_FOREVER  :  datastore - > inheritance  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												AST_LIST_INSERT_TAIL ( & to - > datastores ,  datastore2 ,  entry ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-10 23:29:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_channel_datastore_add ( struct  ast_channel  * chan ,  struct  ast_datastore  * datastore ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-11 03:50:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_LIST_INSERT_HEAD ( & chan - > datastores ,  datastore ,  entry ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-10 23:29:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_datastore_remove ( struct  ast_channel  * chan ,  struct  ast_datastore  * datastore ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-14 00:54:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  AST_LIST_REMOVE ( & chan - > datastores ,  datastore ,  entry )  ?  0  :  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-10 23:29:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-28 18:32:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_datastore  * ast_channel_datastore_find ( struct  ast_channel  * chan ,  const  struct  ast_datastore_info  * info ,  const  char  * uid ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-10 23:29:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * datastore  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( info  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-05-03 19:55:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_LIST_TRAVERSE ( & chan - > datastores ,  datastore ,  entry )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-05 16:56:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( datastore - > info  ! =  info )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( uid  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* matched by type only */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ( datastore - > uid  ! =  NULL )  & &  ! strcasecmp ( uid ,  datastore - > uid ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* Matched by type AND uid */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-10 23:29:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  datastore ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! Set the file descriptor on the channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_channel_set_fd ( struct  ast_channel  * chan ,  int  which ,  int  fd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef HAVE_EPOLL 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  epoll_event  ev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_epoll_data  * aed  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan - > fds [ which ]  >  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										epoll_ctl ( chan - > epfd ,  EPOLL_CTL_DEL ,  chan - > fds [ which ] ,  & ev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										aed  =  chan - > epfd_data [ which ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* If this new fd is valid, add it to the epoll */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( fd  >  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! aed  & &  ( ! ( aed  =  ast_calloc ( 1 ,  sizeof ( * aed ) ) ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > epfd_data [ which ]  =  aed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										aed - > chan  =  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										aed - > which  =  which ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ev . events  =  EPOLLIN  |  EPOLLPRI  |  EPOLLERR  |  EPOLLHUP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ev . data . ptr  =  aed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										epoll_ctl ( chan - > epfd ,  EPOLL_CTL_ADD ,  fd ,  & ev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( aed )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* We don't have to keep around this epoll data structure now */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										free ( aed ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > epfd_data [ which ]  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									chan - > fds [ which ]  =  fd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! Add a channel to an optimized waitfor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_poll_channel_add ( struct  ast_channel  * chan0 ,  struct  ast_channel  * chan1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef HAVE_EPOLL 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  epoll_event  ev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan0 - > epfd  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Iterate through the file descriptors on chan1, adding them to chan0 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( i  =  0 ;  i  <  AST_MAX_FDS ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( chan1 - > fds [ i ]  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ev . events  =  EPOLLIN  |  EPOLLPRI  |  EPOLLERR  |  EPOLLHUP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ev . data . ptr  =  chan1 - > epfd_data [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										epoll_ctl ( chan0 - > epfd ,  EPOLL_CTL_ADD ,  chan1 - > fds [ i ] ,  & ev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! Delete a channel from an optimized waitfor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_poll_channel_del ( struct  ast_channel  * chan0 ,  struct  ast_channel  * chan1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef HAVE_EPOLL 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  epoll_event  ev ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  i  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan0 - > epfd  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( i  =  0 ;  i  <  AST_MAX_FDS ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( chan1 - > fds [ i ]  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										epoll_ctl ( chan0 - > epfd ,  EPOLL_CTL_DEL ,  chan1 - > fds [ i ] ,  & ev ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 303548 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.6.2
................
  r303548 | russell | 2011-01-24 14:49:53 -0600 (Mon, 24 Jan 2011) | 38 lines
  
  Merged revisions 303546 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r303546 | russell | 2011-01-24 14:32:21 -0600 (Mon, 24 Jan 2011) | 31 lines
    
    Fix channel redirect out of MeetMe() and other issues with channel softhangup.
    
    Mantis issue #18585 reports that a channel redirect out of MeetMe() stopped
    working properly.  This issue includes a patch that resolves the issue by
    removing a call to ast_check_hangup() from app_meetme.c.  I left that in my
    patch, as it doesn't need to be there.  However, the rest of the patch fixes
    this problem with or without the change to app_meetme.
    
    The key difference between what happens before and after this patch is the
    effect of the END_OF_Q control frame.  After END_OF_Q is hit in ast_read(),
    ast_read() will return NULL.  With the ast_check_hangup() removed, app_meetme
    sees this which causes it to exit as intended.  Checking ast_check_hangup()
    caused app_meetme to exit earlier in the process, and the target of the
    redirect saw the condition where ast_read() returned NULL.
    
    Removing ast_check_hangup() works around the issue in app_meetme, but doesn't
    solve the issue if another application did the same thing.  There are also
    other edge cases where if an application finishes at the same time that a
    redirect happens, the target of the redirect will think that the channel hung
    up.  So, I made some changes in pbx.c to resolve it at a deeper level.  There
    are already places that unset the SOFTHANGUP_ASYNCGOTO flag in an attempt to
    abort the hangup process.  My patch extends this to remove the END_OF_Q frame
    from the channel's read queue, making the "abort hangup" more complete.  This
    same technique was used in every place where a softhangup flag was cleared.
    
    (closes issue #18585)
    Reported by: oej
    Tested by: oej, wedhorn, russell
    
    Review: https://reviewboard.asterisk.org/r/1082/
  ........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@303549 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2011-01-24 20:51:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channel_clear_softhangup ( struct  ast_channel  * chan ,  int  flag ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									chan - > _softhangup  & =  ~ flag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! chan - > _softhangup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										struct  ast_frame  * fr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* If we have completely cleared the softhangup flag,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  then  we  need  to  fully  abort  the  hangup  process .   This  requires 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  pulling  the  END_OF_Q  frame  out  of  the  channel  frame  queue  if  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  still  happens  to  be  there .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										fr  =  AST_LIST_LAST ( & chan - > readq ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( fr  & &  fr - > frametype  = =  AST_FRAME_CONTROL  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												fr - > subclass . integer  = =  AST_CONTROL_END_OF_Q )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											AST_LIST_REMOVE ( & chan - > readq ,  fr ,  frame_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_frfree ( fr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Softly hangup a channel, don't lock */ 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_softhangup_nolock ( struct  ast_channel  * chan ,  int  cause ) 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_debug ( 1 ,  " Soft-Hanging up channel '%s' \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Inform channel driver that we need to be hung up, if it cares */ 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									chan - > _softhangup  | =  cause ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_queue_frame ( chan ,  & ast_null_frame ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 03:02:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Interrupt any poll call or such */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( chan ,  AST_FLAG_BLOCKING ) ) 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										pthread_kill ( chan - > blocker ,  SIGURG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Softly hangup a channel, lock */ 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_softhangup ( struct  ast_channel  * chan ,  int  cause ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-09 16:48:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									res  =  ast_softhangup_nolock ( chan ,  cause ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-09 16:48:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  free_translation ( struct  ast_channel  * clonechan ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( clonechan - > writetrans ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_translator_free_path ( clonechan - > writetrans ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( clonechan - > readtrans ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_translator_free_path ( clonechan - > readtrans ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > writetrans  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > readtrans  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > rawwriteformat  =  clonechan - > nativeformats ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > rawreadformat  =  clonechan - > nativeformats ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_set_hangupsource ( struct  ast_channel  * chan ,  const  char  * source ,  int  force ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * bridge ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( force  | |  ast_strlen_zero ( chan - > hangupsource ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_set ( chan ,  hangupsource ,  source ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									bridge  =  ast_bridged_channel ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( bridge  & &  ( force  | |  ast_strlen_zero ( bridge - > hangupsource ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_lock ( bridge ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_set ( chan ,  hangupsource ,  source ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( bridge ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Hangup a channel */ 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								int  ast_hangup ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  extra_str [ 64 ] ;  /* used for cel logging below */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_autoservice_stop ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ao2_lock ( channels ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 15:07:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-23 21:52:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 19:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > audiohooks )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_audiohook_detach_list ( chan - > audiohooks ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > audiohooks  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_framehook_list_destroy ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Do  the  masquerade  if  someone  is  setup  to  masquerade  into  us . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  NOTE :  We  must  hold  the  channel  lock  after  testing  for  a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  pending  masquerade  and  setting  the  channel  as  a  zombie  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  prevent  __ast_channel_masquerade ( )  from  setting  up  a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  masquerade  with  a  dead  channel . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									while  ( chan - > masq )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ao2_unlock ( channels ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ast_do_masquerade ( chan ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Failed to perform masquerade \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* Abort the loop or we might never leave. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ao2_lock ( channels ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ao2_lock ( channels ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > masqr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  This  channel  is  one  which  will  be  masqueraded  into  something . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  Mark  it  as  a  zombie  already  so  ast_do_masquerade ( )  will  know 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  to  free  it  later . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_set_flag ( chan ,  AST_FLAG_ZOMBIE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 15:07:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ao2_unlock ( channels ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-17 15:18:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ao2_unlink ( channels ,  chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ao2_unlock ( channels ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-17 15:18:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									free_translation ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-07 00:17:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Close audio stream */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan - > stream )  { 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-02 23:25:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_closestream ( chan - > stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-07 00:17:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > stream  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Close video stream */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan - > vstream )  { 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-02 23:25:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_closestream ( chan - > vstream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-07 00:17:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > vstream  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 7265-7266,7268-7275 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2
........
r7265 | oej | 2005-12-01 17:18:14 -0600 (Thu, 01 Dec 2005) | 2 lines
Changing bug report address to the Asterisk issue tracker
........
r7266 | kpfleming | 2005-12-01 17:18:29 -0600 (Thu, 01 Dec 2005) | 3 lines
Makefile 'update' target now supports updating from Subversion repositories (issue #5875)
remove support for 'patches' subdirectory, it's no longer useful
........
r7268 | kpfleming | 2005-12-01 17:34:58 -0600 (Thu, 01 Dec 2005) | 2 lines
ensure channel's scheduling context is freed (issue #5788)
........
r7269 | kpfleming | 2005-12-01 17:49:44 -0600 (Thu, 01 Dec 2005) | 2 lines
don't block waiting for the Festival server forever when it goes away (issue #5882)
........
r7270 | kpfleming | 2005-12-01 18:26:12 -0600 (Thu, 01 Dec 2005) | 2 lines
allow variables to exist on both 'halves' of the Local channel (issue #5810)
........
r7271 | kpfleming | 2005-12-01 18:28:48 -0600 (Thu, 01 Dec 2005) | 2 lines
protect agent_bridgedchannel() from segfaulting when there is no bridged channel (issue #5879)
........
r7272 | kpfleming | 2005-12-01 18:39:00 -0600 (Thu, 01 Dec 2005) | 3 lines
properly handle password changes when mailbox is last line of config file and not followed by a newline (issue #5870)
reformat password changing code to conform to coding guidelines (issue #5870)
........
r7273 | kpfleming | 2005-12-01 18:42:40 -0600 (Thu, 01 Dec 2005) | 2 lines
allow previous context-searching behavior to be used if desired (issue #5899)
........
r7274 | kpfleming | 2005-12-01 18:51:15 -0600 (Thu, 01 Dec 2005) | 2 lines
inherit channel variables into channels created by Page() application (issue #5888)
........
r7275 | oej | 2005-12-01 18:52:13 -0600 (Thu, 01 Dec 2005) | 2 lines
Bug #5907. Improve SIP INFO DTMF debugging output. (1.2 & Trunk)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7276 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2005-12-02 01:01:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > sched )  { 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										sched_context_destroy ( chan - > sched ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 7265-7266,7268-7275 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.2
........
r7265 | oej | 2005-12-01 17:18:14 -0600 (Thu, 01 Dec 2005) | 2 lines
Changing bug report address to the Asterisk issue tracker
........
r7266 | kpfleming | 2005-12-01 17:18:29 -0600 (Thu, 01 Dec 2005) | 3 lines
Makefile 'update' target now supports updating from Subversion repositories (issue #5875)
remove support for 'patches' subdirectory, it's no longer useful
........
r7268 | kpfleming | 2005-12-01 17:34:58 -0600 (Thu, 01 Dec 2005) | 2 lines
ensure channel's scheduling context is freed (issue #5788)
........
r7269 | kpfleming | 2005-12-01 17:49:44 -0600 (Thu, 01 Dec 2005) | 2 lines
don't block waiting for the Festival server forever when it goes away (issue #5882)
........
r7270 | kpfleming | 2005-12-01 18:26:12 -0600 (Thu, 01 Dec 2005) | 2 lines
allow variables to exist on both 'halves' of the Local channel (issue #5810)
........
r7271 | kpfleming | 2005-12-01 18:28:48 -0600 (Thu, 01 Dec 2005) | 2 lines
protect agent_bridgedchannel() from segfaulting when there is no bridged channel (issue #5879)
........
r7272 | kpfleming | 2005-12-01 18:39:00 -0600 (Thu, 01 Dec 2005) | 3 lines
properly handle password changes when mailbox is last line of config file and not followed by a newline (issue #5870)
reformat password changing code to conform to coding guidelines (issue #5870)
........
r7273 | kpfleming | 2005-12-01 18:42:40 -0600 (Thu, 01 Dec 2005) | 2 lines
allow previous context-searching behavior to be used if desired (issue #5899)
........
r7274 | kpfleming | 2005-12-01 18:51:15 -0600 (Thu, 01 Dec 2005) | 2 lines
inherit channel variables into channels created by Page() application (issue #5888)
........
r7275 | oej | 2005-12-01 18:52:13 -0600 (Thu, 01 Dec 2005) | 2 lines
Bug #5907. Improve SIP INFO DTMF debugging output. (1.2 & Trunk)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@7276 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2005-12-02 01:01:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > sched  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > generatordata )  { 	/* Clear any tone stuff remaining */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( chan - > generator  & &  chan - > generator - > release )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-12-21 19:36:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											chan - > generator - > release ( chan ,  chan - > generatordata ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									chan - > generatordata  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									chan - > generator  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									snprintf ( extra_str ,  sizeof ( extra_str ) ,  " %d,%s,%s " ,  chan - > hangupcause ,  chan - > hangupsource ,  S_OR ( pbx_builtin_getvar_helper ( chan ,  " DIALSTATUS " ) ,  " " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_cel_report_event ( chan ,  AST_CEL_HANGUP ,  NULL ,  extra_str ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( chan ,  AST_FLAG_BLOCKING ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Hard hangup called by thread %ld on %s, while fd  " 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											" is blocked by thread %ld in procedure %s!  Expect a failure \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											( long )  pthread_self ( ) ,  chan - > name ,  ( long ) chan - > blocker ,  chan - > blockproc ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-11 18:19:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_assert ( ast_test_flag ( chan ,  AST_FLAG_BLOCKING )  = =  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ast_test_flag ( chan ,  AST_FLAG_ZOMBIE ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_debug ( 1 ,  " Hanging up channel '%s' \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  This  channel  is  now  dead  so  mark  it  as  a  zombie  so  anyone 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  left  holding  a  reference  to  this  channel  will  not  use  it . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_set_flag ( chan ,  AST_FLAG_ZOMBIE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( chan - > tech - > hangup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											chan - > tech - > hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_debug ( 1 ,  " Hanging up zombie '%s' \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 15:07:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merge Call completion support into trunk.
From Reviewboard:
CCSS stands for Call Completion Supplementary Services. An admittedly out-of-date
overview of the architecture can be found in the file doc/CCSS_architecture.pdf
in the CCSS branch. Off the top of my head, the big differences between what is
implemented and what is in the document are as follows:
1. We did not end up modifying the Hangup application at all.
2. The document states that a single call completion monitor may be used across
   multiple calls to the same device. This proved to not be such a good idea
   when implementing protocol-specific monitors, and so we ended up using one
   monitor per-device per-call.
3. There are some configuration options which were conceived after the document
   was written. These are documented in the ccss.conf.sample that is on this
   review request.
		      
For some basic understanding of terminology used throughout this code, see the
ccss.tex document that is on this review.
This implements CCBS and CCNR in several flavors.
First up is a "generic" implementation, which can work over any channel technology
provided that the channel technology can accurately report device state. Call
completion is requested using the dialplan application CallCompletionRequest and can
be canceled using CallCompletionCancel. Device state subscriptions are used in order
to monitor the state of called parties.
Next, there is a SIP-specific implementation of call completion. This method uses the
methods outlined in draft-ietf-bliss-call-completion-06 to implement call completion
using SIP signaling. There are a few things to note here:
* The agent/monitor terminology used throughout Asterisk sometimes is the reverse of
  what is defined in the referenced draft.
* Implementation of the draft required support for SIP PUBLISH. I attempted to write
  this in a generic-enough fashion such that if someone were to want to write PUBLISH
  support for other event packages, such as dialog-state or presence, most of the effort
  would be in writing callbacks specific to the event package.
* A subportion of supporting PUBLISH reception was that we had to implement a PIDF
  parser. The PIDF support added is a bit minimal. I first wrote a validation
  routine to ensure that the PIDF document is formatted properly. The rest of the
  PIDF reading is done in-line in the call-completion-specific PUBLISH-handling
  code. In other words, while there is PIDF support here, it is not in any state
  where it could easily be applied to other event packages as is.
Finally, there are a variety of ISDN-related call completion protocols supported. These
were written by Richard Mudgett, and as such I can't really say much about their
implementation. There are notes in the CHANGES file that indicate the ISDN protocols
over which call completion is supported.
Review: https://reviewboard.asterisk.org/r/523
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-04-09 15:31:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_cc_offer ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_manager_event ( chan ,  EVENT_FLAG_CALL ,  " Hangup " , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										" Channel: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" Uniqueid: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" CallerIDNum: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" CallerIDName: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-25 17:06:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										" ConnectedLineNum: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" ConnectedLineName: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										" Cause: %d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" Cause-txt: %s \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > uniqueid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										S_COR ( chan - > caller . id . number . valid ,  chan - > caller . id . number . str ,  " <unknown> " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										S_COR ( chan - > caller . id . name . valid ,  chan - > caller . id . name . str ,  " <unknown> " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-25 17:06:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										S_COR ( chan - > connected . id . number . valid ,  chan - > connected . id . number . str ,  " <unknown> " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										S_COR ( chan - > connected . id . name . valid ,  chan - > connected . id . name . str ,  " <unknown> " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > hangupcause , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_cause2str ( chan - > hangupcause ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-27 20:26:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > cdr  & &  ! ast_test_flag ( chan - > cdr ,  AST_CDR_FLAG_BRIDGED )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										! ast_test_flag ( chan - > cdr ,  AST_CDR_FLAG_POST_DISABLED )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										( chan - > cdr - > disposition  ! =  AST_CDR_NULL  | |  ast_test_flag ( chan - > cdr ,  AST_CDR_FLAG_DIALED ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-06 21:46:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_cdr_end ( chan - > cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_cdr_detach ( chan - > cdr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-02 22:50:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > cdr  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-06 21:46:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unref ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-27 20:26:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												Improve behavior of ast_answer() to not lose incoming frames
ast_answer(), when supplied a delay before returning to the caller, use ast_safe_sleep() to implement the delay. Unfortunately during this time any incoming frames are discarded, which is problematic for T.38 re-INVITES and other sorts of channel operations.
When a delay is not passed to ast_answer(), it still delays for up to 500 milliseconds, waiting for media to arrive. Again, though, it discards any control frames, or non-voice media frames.
This patch rectifies this situation, by storing all incoming frames during the delay period on a list, and then requeuing them onto the channel before returning to the caller.
http://reviewboard.digium.com/r/196/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@182525 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-03-17 14:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_raw_answer ( struct  ast_channel  * chan ,  int  cdr_answer ) 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-11 23:42:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 15:07:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-11 23:42:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-09 15:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* You can't answer an outbound call */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-06 05:27:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( chan ,  AST_FLAG_OUTGOING ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-09 15:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-06 05:27:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-11 23:42:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Stop if we're a zombie or need a soft hangup */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( chan ,  AST_FLAG_ZOMBIE )  | |  ast_check_hangup ( chan ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-06-23 17:41:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-11 23:42:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-09-09 01:47:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-01-23 00:11:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									switch  ( chan - > _state )  { 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_STATE_RINGING : 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_STATE_RING : 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-09 01:47:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( chan - > tech - > answer )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-07 19:36:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											res  =  chan - > tech - > answer ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-09 01:47:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-07 19:36:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_setstate ( chan ,  AST_STATE_UP ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-11 22:41:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( cdr_answer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_cdr_answer ( chan - > cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_cel_report_event ( chan ,  AST_CEL_ANSWER ,  NULL ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-09 01:47:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
											
												Improve behavior of ast_answer() to not lose incoming frames
ast_answer(), when supplied a delay before returning to the caller, use ast_safe_sleep() to implement the delay. Unfortunately during this time any incoming frames are discarded, which is problematic for T.38 re-INVITES and other sorts of channel operations.
When a delay is not passed to ast_answer(), it still delays for up to 500 milliseconds, waiting for media to arrive. Again, though, it discards any control frames, or non-voice media frames.
This patch rectifies this situation, by storing all incoming frames during the delay period on a list, and then requeuing them onto the channel before returning to the caller.
http://reviewboard.digium.com/r/196/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@182525 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-03-17 14:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_STATE_UP : 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_cel_report_event ( chan ,  AST_CEL_ANSWER ,  NULL ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
											
												Improve behavior of ast_answer() to not lose incoming frames
ast_answer(), when supplied a delay before returning to the caller, use ast_safe_sleep() to implement the delay. Unfortunately during this time any incoming frames are discarded, which is problematic for T.38 re-INVITES and other sorts of channel operations.
When a delay is not passed to ast_answer(), it still delays for up to 500 milliseconds, waiting for media to arrive. Again, though, it discards any control frames, or non-voice media frames.
This patch rectifies this situation, by storing all incoming frames during the delay period on a list, and then requeuing them onto the channel before returning to the caller.
http://reviewboard.digium.com/r/196/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@182525 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-03-17 14:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* Calling ast_cdr_answer when it it has previously been called
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  is  essentially  a  no - op ,  so  it  is  safe . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( cdr_answer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_cdr_answer ( chan - > cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_indicate ( chan ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  __ast_answer ( struct  ast_channel  * chan ,  unsigned  int  delay ,  int  cdr_answer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enum  ast_channel_state  old_state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									old_state  =  chan - > _state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( res  =  ast_raw_answer ( chan ,  cdr_answer ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( old_state )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_STATE_RINGING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_STATE_RING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* wait for media to start flowing, but don't wait any longer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  than  ' delay '  or  500  milliseconds ,  whichever  is  longer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											AST_LIST_HEAD_NOLOCK ( ,  ast_frame )  frames ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											struct  ast_frame  * cur ,  * new ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											int  ms  =  MAX ( delay ,  500 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											unsigned  int  done  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											AST_LIST_HEAD_INIT_NOLOCK ( & frames ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-07 19:54:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ms  =  ast_waitfor ( chan ,  ms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( ms  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-07 19:36:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_log ( LOG_WARNING ,  " Error condition occurred when polling channel %s for a voice frame: %s \n " ,  chan - > name ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-07 19:54:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-07 19:36:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-07 19:54:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( ms  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
											
												Improve behavior of ast_answer() to not lose incoming frames
ast_answer(), when supplied a delay before returning to the caller, use ast_safe_sleep() to implement the delay. Unfortunately during this time any incoming frames are discarded, which is problematic for T.38 re-INVITES and other sorts of channel operations.
When a delay is not passed to ast_answer(), it still delays for up to 500 milliseconds, waiting for media to arrive. Again, though, it discards any control frames, or non-voice media frames.
This patch rectifies this situation, by storing all incoming frames during the delay period on a list, and then requeuing them onto the channel before returning to the caller.
http://reviewboard.digium.com/r/196/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@182525 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-03-17 14:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_debug ( 2 ,  " Didn't receive a media frame from %s within %d ms of answering. Continuing anyway \n " ,  chan - > name ,  MAX ( delay ,  500 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-07 19:36:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
											
												Improve behavior of ast_answer() to not lose incoming frames
ast_answer(), when supplied a delay before returning to the caller, use ast_safe_sleep() to implement the delay. Unfortunately during this time any incoming frames are discarded, which is problematic for T.38 re-INVITES and other sorts of channel operations.
When a delay is not passed to ast_answer(), it still delays for up to 500 milliseconds, waiting for media to arrive. Again, though, it discards any control frames, or non-voice media frames.
This patch rectifies this situation, by storing all incoming frames during the delay period on a list, and then requeuing them onto the channel before returning to the caller.
http://reviewboard.digium.com/r/196/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@182525 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-03-17 14:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												cur  =  ast_read ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( ! cur  | |  ( ( cur - > frametype  = =  AST_FRAME_CONTROL )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													     ( cur - > subclass . integer  = =  AST_CONTROL_HANGUP ) ) )  { 
							 
						 
					
						
							
								
									
										
										
											
												Improve behavior of ast_answer() to not lose incoming frames
ast_answer(), when supplied a delay before returning to the caller, use ast_safe_sleep() to implement the delay. Unfortunately during this time any incoming frames are discarded, which is problematic for T.38 re-INVITES and other sorts of channel operations.
When a delay is not passed to ast_answer(), it still delays for up to 500 milliseconds, waiting for media to arrive. Again, though, it discards any control frames, or non-voice media frames.
This patch rectifies this situation, by storing all incoming frames during the delay period on a list, and then requeuing them onto the channel before returning to the caller.
http://reviewboard.digium.com/r/196/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@182525 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-03-17 14:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													if  ( cur )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														ast_frfree ( cur ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-16 13:58:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-07 19:36:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_debug ( 2 ,  " Hangup of channel %s detected in answer routine \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
											
												Improve behavior of ast_answer() to not lose incoming frames
ast_answer(), when supplied a delay before returning to the caller, use ast_safe_sleep() to implement the delay. Unfortunately during this time any incoming frames are discarded, which is problematic for T.38 re-INVITES and other sorts of channel operations.
When a delay is not passed to ast_answer(), it still delays for up to 500 milliseconds, waiting for media to arrive. Again, though, it discards any control frames, or non-voice media frames.
This patch rectifies this situation, by storing all incoming frames during the delay period on a list, and then requeuing them onto the channel before returning to the caller.
http://reviewboard.digium.com/r/196/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@182525 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-03-17 14:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( ( new  =  ast_frisolate ( cur ) )  ! =  cur )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_frfree ( cur ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-17 15:22:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												AST_LIST_INSERT_HEAD ( & frames ,  new ,  frame_list ) ; 
							 
						 
					
						
							
								
									
										
										
											
												Improve behavior of ast_answer() to not lose incoming frames
ast_answer(), when supplied a delay before returning to the caller, use ast_safe_sleep() to implement the delay. Unfortunately during this time any incoming frames are discarded, which is problematic for T.38 re-INVITES and other sorts of channel operations.
When a delay is not passed to ast_answer(), it still delays for up to 500 milliseconds, waiting for media to arrive. Again, though, it discards any control frames, or non-voice media frames.
This patch rectifies this situation, by storing all incoming frames during the delay period on a list, and then requeuing them onto the channel before returning to the caller.
http://reviewboard.digium.com/r/196/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@182525 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-03-17 14:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* if a specific delay period was requested, continue
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 *  until  that  delay  has  passed .  don ' t  stop  just  because 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 *  incoming  media  has  arrived . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( delay )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												switch  ( new - > frametype )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													/* all of these frametypes qualify as 'media' */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_FRAME_VOICE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_FRAME_VIDEO : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_FRAME_TEXT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_FRAME_DTMF_BEGIN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_FRAME_DTMF_END : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_FRAME_IMAGE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_FRAME_HTML : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_FRAME_MODEM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													done  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_FRAME_CONTROL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_FRAME_IAX : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_FRAME_NULL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_FRAME_CNG : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( done )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-07 19:36:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-01 19:53:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
											
												Improve behavior of ast_answer() to not lose incoming frames
ast_answer(), when supplied a delay before returning to the caller, use ast_safe_sleep() to implement the delay. Unfortunately during this time any incoming frames are discarded, which is problematic for T.38 re-INVITES and other sorts of channel operations.
When a delay is not passed to ast_answer(), it still delays for up to 500 milliseconds, waiting for media to arrive. Again, though, it discards any control frames, or non-voice media frames.
This patch rectifies this situation, by storing all incoming frames during the delay period on a list, and then requeuing them onto the channel before returning to the caller.
http://reviewboard.digium.com/r/196/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@182525 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-03-17 14:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( res  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-17 15:22:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												while  ( ( cur  =  AST_LIST_REMOVE_HEAD ( & frames ,  frame_list ) ) )  { 
							 
						 
					
						
							
								
									
										
										
											
												Improve behavior of ast_answer() to not lose incoming frames
ast_answer(), when supplied a delay before returning to the caller, use ast_safe_sleep() to implement the delay. Unfortunately during this time any incoming frames are discarded, which is problematic for T.38 re-INVITES and other sorts of channel operations.
When a delay is not passed to ast_answer(), it still delays for up to 500 milliseconds, waiting for media to arrive. Again, though, it discards any control frames, or non-voice media frames.
This patch rectifies this situation, by storing all incoming frames during the delay period on a list, and then requeuing them onto the channel before returning to the caller.
http://reviewboard.digium.com/r/196/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@182525 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-03-17 14:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_queue_frame_head ( chan ,  cur ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_frfree ( cur ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  while  ( 0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-19 03:50:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-09-09 01:47:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:22:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-01-12 15:01:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_answer ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-11 22:41:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  __ast_answer ( chan ,  0 ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-12 15:01:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-04-07 14:43:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_deactivate_generator ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > generatordata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( chan - > generator  & &  chan - > generator - > release ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-02-04 23:18:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											chan - > generator - > release ( chan ,  chan - > generatordata ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > generatordata  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > generator  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_set_fd ( chan ,  AST_GENERATOR_FD ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_clear_flag ( chan ,  AST_FLAG_WRITE_INT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-27 03:28:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_settimeout ( chan ,  0 ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-02 21:58:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-07 14:43:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-09-21 14:40:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  generator_force ( const  void  * data ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-27 03:28:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Called if generator doesn't have data */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									void  * tmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-10 17:13:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  ( * generate ) ( struct  ast_channel  * chan ,  void  * tmp ,  int  datalen ,  int  samples )  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-21 14:40:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * chan  =  ( struct  ast_channel  * ) data ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 17:21:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-27 03:28:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									tmp  =  chan - > generatordata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									chan - > generatordata  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-10 16:59:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > generator ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										generate  =  chan - > generator - > generate ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 17:21:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-03-10 16:59:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! tmp  | |  ! generate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Add some fixes that I made in regards to wideband codec handling to get
G.722 music on hold working for me.
(issue #12164, reported by milazzo and jsmith, patches by me)
res/res_musiconhold.c:
 - I moved a single line so that the sample queue update happened before
   ast_write().  The reason that this was a bug is that the G.722 frame
   originally says it has 320 samples in it (which is correct).  However,
   when the frame is written to a channel that uses RTP, main/rtp.c modifies
   the frame to cut the number of samples in half before it sends it on
   the wire.  This is to account for the stupid incorrect G.722 spec that
   makes it so we have to lie about the number of samples with RTP.  I should
   probably go and re-work the RTP code so it doesn't modify the frame so
   that a bug like this won't happen in the future.  However, this change to
   MOH is harmless.
main/channel.c:
 - I made two fixes in regards to generator timing.  Generators use samples
   for timing.  However, this code assumed 8 kHz samples.  In one case, it was
   a hard coded 160 samples, that is now written as the sample rate / 50.  The
   other place was dealing with timing a generator based on frames coming from
   the other direction.  However, that would have only worked if the sample
   rates for the formats in both directions were the same.  The code now takes
   into account that the sample rates may differ, and scales the generator
   samples accordingly.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@110268 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-03-20 17:41:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									res  =  generate ( chan ,  tmp ,  0 ,  ast_format_rate ( chan - > writeformat  &  AST_FORMAT_AUDIO_MASK )  /  50 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 17:21:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-08-27 03:28:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									chan - > generatordata  =  tmp ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 17:21:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-08-27 03:28:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_debug ( 1 ,  " Auto-deactivating generator \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-08-27 03:28:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_deactivate_generator ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 17:21:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-08-27 03:28:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_activate_generator ( struct  ast_channel  * chan ,  struct  ast_generator  * gen ,  void  * params ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2004-06-02 20:18:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-28 23:01:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 15:07:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > generatordata )  { 
							 
						 
					
						
							
								
									
										
										
										
											2004-02-04 23:18:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( chan - > generator  & &  chan - > generator - > release ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											chan - > generator - > release ( chan ,  chan - > generatordata ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > generatordata  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-15 01:48:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( gen - > alloc  & &  ! ( chan - > generatordata  =  gen - > alloc ( chan ,  params ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-28 23:01:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 12:45:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_settimeout ( chan ,  50 ,  generator_force ,  chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > generator  =  gen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 15:07:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-28 23:01:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-28 21:20:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_prod ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-06-02 20:18:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Wait for x amount of time on a file descriptor to have input.  */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_waitfor_n_fd ( int  * fds ,  int  n ,  int  * ms ,  int  * exception ) 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  winner  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_waitfor_nandfds ( NULL ,  0 ,  fds ,  n ,  exception ,  & winner ,  ms ) ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									return  winner ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Wait for x amount of time on a file descriptor to have input.  */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef HAVE_EPOLL 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  struct  ast_channel  * ast_waitfor_nandfds_classic ( struct  ast_channel  * * c ,  int  n ,  int  * fds ,  int  nfds , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													int  * exception ,  int  * outfd ,  int  * ms ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# else 
 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_waitfor_nandfds ( struct  ast_channel  * * c ,  int  n ,  int  * fds ,  int  nfds , 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													int  * exception ,  int  * outfd ,  int  * ms ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-27 22:19:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  timeval  start  =  {  0  ,  0  } ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												3) In addition to merging the changes below, change trunk back to a regular
   LIST instead of an RWLIST.  The way this list works makes it such that
   a RWLIST provides no additional benefit.  Also, a mutex is needed for
   use with the thread condition.
Merged revisions 105563 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r105563 | russell | 2008-03-03 09:50:43 -0600 (Mon, 03 Mar 2008) | 24 lines
Merge in some changes from team/russell/autoservice-nochans-1.4
These changes fix up some dubious code that I came across while auditing what
happens in the autoservice thread when there are no channels currently in
autoservice.
1) Change it so that autoservice thread doesn't keep looping around calling
   ast_waitfor_n() on 0 channels twice a second.  Instead, use a thread condition
   so that the thread properly goes to sleep and does not wake up until a
   channel is put into autoservice.
   This actually fixes an interesting bug, as well.  If the autoservice thread
   is already running (almost always is the case), then when the thread goes
   from having 0 channels to have 1 channel to autoservice, that channel would
   have to wait for up to 1/2 of a second to have the first frame read from it.
2) Fix up the code in ast_waitfor_nandfds() for when it gets called with no
   channels and no fds to poll() on, such as was the case with the previous code
   for the autoservice thread.  In this case, the code would call alloca(0), and
   pass the result as the first argument to poll().  In this case, the 2nd
   argument to poll() specified that there were no fds, so this invalid pointer
   shouldn't actually get dereferenced, but, this code makes it explicit and
   ensures the pointers are NULL unless we have valid data to put there.
(related to issue #12116)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@105564 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-03-03 15:59:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  pollfd  * pfds  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-25 20:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									long  rms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  x ,  y ,  max ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  sz ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  timeval  now  =  {  0 ,  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  timeval  whentohangup  =  {  0 ,  0  } ,  diff ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * winner  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  fdmap  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  fdno ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												3) In addition to merging the changes below, change trunk back to a regular
   LIST instead of an RWLIST.  The way this list works makes it such that
   a RWLIST provides no additional benefit.  Also, a mutex is needed for
   use with the thread condition.
Merged revisions 105563 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r105563 | russell | 2008-03-03 09:50:43 -0600 (Mon, 03 Mar 2008) | 24 lines
Merge in some changes from team/russell/autoservice-nochans-1.4
These changes fix up some dubious code that I came across while auditing what
happens in the autoservice thread when there are no channels currently in
autoservice.
1) Change it so that autoservice thread doesn't keep looping around calling
   ast_waitfor_n() on 0 channels twice a second.  Instead, use a thread condition
   so that the thread properly goes to sleep and does not wake up until a
   channel is put into autoservice.
   This actually fixes an interesting bug, as well.  If the autoservice thread
   is already running (almost always is the case), then when the thread goes
   from having 0 channels to have 1 channel to autoservice, that channel would
   have to wait for up to 1/2 of a second to have the first frame read from it.
2) Fix up the code in ast_waitfor_nandfds() for when it gets called with no
   channels and no fds to poll() on, such as was the case with the previous code
   for the autoservice thread.  In this case, the code would call alloca(0), and
   pass the result as the first argument to poll().  In this case, the 2nd
   argument to poll() specified that there were no fds, so this invalid pointer
   shouldn't actually get dereferenced, but, this code makes it explicit and
   ensures the pointers are NULL unless we have valid data to put there.
(related to issue #12116)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@105564 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-03-03 15:59:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  * fdmap  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												3) In addition to merging the changes below, change trunk back to a regular
   LIST instead of an RWLIST.  The way this list works makes it such that
   a RWLIST provides no additional benefit.  Also, a mutex is needed for
   use with the thread condition.
Merged revisions 105563 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r105563 | russell | 2008-03-03 09:50:43 -0600 (Mon, 03 Mar 2008) | 24 lines
Merge in some changes from team/russell/autoservice-nochans-1.4
These changes fix up some dubious code that I came across while auditing what
happens in the autoservice thread when there are no channels currently in
autoservice.
1) Change it so that autoservice thread doesn't keep looping around calling
   ast_waitfor_n() on 0 channels twice a second.  Instead, use a thread condition
   so that the thread properly goes to sleep and does not wake up until a
   channel is put into autoservice.
   This actually fixes an interesting bug, as well.  If the autoservice thread
   is already running (almost always is the case), then when the thread goes
   from having 0 channels to have 1 channel to autoservice, that channel would
   have to wait for up to 1/2 of a second to have the first frame read from it.
2) Fix up the code in ast_waitfor_nandfds() for when it gets called with no
   channels and no fds to poll() on, such as was the case with the previous code
   for the autoservice thread.  In this case, the code would call alloca(0), and
   pass the result as the first argument to poll().  In this case, the 2nd
   argument to poll() specified that there were no fds, so this invalid pointer
   shouldn't actually get dereferenced, but, this code makes it explicit and
   ensures the pointers are NULL unless we have valid data to put there.
(related to issue #12116)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@105564 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-03-03 15:59:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ( sz  =  n  *  AST_MAX_FDS  +  nfds ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pfds  =  alloca ( sizeof ( * pfds )  *  sz ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										fdmap  =  alloca ( sizeof ( * fdmap )  *  sz ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-25 20:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( outfd ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-03-05 18:22:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										* outfd  =  - 99999 ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( exception ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* exception  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Perform any pending masquerades */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( x  =  0 ;  x  <  n ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( c [ x ] - > masq  & &  ast_do_masquerade ( c [ x ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Masquerade failed \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* ms  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_lock ( c [ x ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! ast_tvzero ( c [ x ] - > whentohangup ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ast_tvzero ( whentohangup ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												now  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											diff  =  ast_tvsub ( c [ x ] - > whentohangup ,  now ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( diff . tv_sec  <  0  | |  ast_tvzero ( diff ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												/* Should already be hungup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												c [ x ] - > _softhangup  | =  AST_SOFTHANGUP_TIMEOUT ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 15:07:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_channel_unlock ( c [ x ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												return  c [ x ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ast_tvzero ( whentohangup )  | |  ast_tvcmp ( diff ,  whentohangup )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												whentohangup  =  diff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 15:07:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( c [ x ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Wait full interval */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-25 20:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									rms  =  * ms ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-04 23:51:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* INT_MAX, not LONG_MAX, because it matters on 64-bit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_tvzero ( whentohangup )  & &  whentohangup . tv_sec  <  INT_MAX  /  1000 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										rms  =  whentohangup . tv_sec  *  1000  +  whentohangup . tv_usec  /  1000 ;               /* timeout in milliseconds */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-04 23:51:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( * ms  > =  0  & &  * ms  <  rms )  {                                                  /* original *ms still smaller */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											rms  =   * ms ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-04 23:51:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( ! ast_tvzero ( whentohangup )  & &  rms  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Tiny corner case... call would need to last >24 days */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										rms  =  INT_MAX ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-03-05 18:22:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Build  the  pollfd  array ,  putting  the  channels '  fds  first , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  followed  by  individual  fds .  Order  is  important  because 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  individual  fd ' s  must  have  priority  over  channel  fds . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-25 20:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									max  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( x  =  0 ;  x  <  n ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										for  ( y  =  0 ;  y  <  AST_MAX_FDS ;  y + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											fdmap [ max ] . fdno  =  y ;   /* fd y is linked to this pfds */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											fdmap [ max ] . chan  =  x ;   /* channel x is linked to this pfds */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											max  + =  ast_add_fd ( & pfds [ max ] ,  c [ x ] - > fds [ y ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										CHECK_BLOCKING ( c [ x ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Add the individual fds */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( x  =  0 ;  x  <  nfds ;  x + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										fdmap [ max ] . chan  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										max  + =  ast_add_fd ( & pfds [ max ] ,  fds [ x ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( * ms  >  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 23:00:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										start  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-20 22:45:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( sizeof ( int )  = =  4 )  { 	/* XXX fix timeout > 600000 on linux x86-32 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-20 22:45:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											int  kbrms  =  rms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( kbrms  >  600000 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												kbrms  =  600000 ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 182810 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r182810 | russell | 2009-03-17 21:09:13 -0500 (Tue, 17 Mar 2009) | 44 lines
Fix cases where the internal poll() was not being used when it needed to be.
We have seen a number of problems caused by poll() not working properly on 
Mac OSX.  If you search around, you'll find a number of references to using 
select() instead of poll() to work around these issues.  In Asterisk, we've 
had poll.c which implements poll() using select() internally.  However, we 
were still getting reports of problems.
vadim investigated a bit and realized that at least on his system, even 
though we were compiling in poll.o, the system poll() was still being used.  
So, the primary purpose of this patch is to ensure that we're using the 
internal poll() when we want it to be used.
The changes are:
1) Remove logic for when internal poll should be used from the Makefile.  
   Instead, put it in the configure script.  The logic in the configure 
   script is the same as it was in the Makefile.  Ideally, we would have 
   a functionality test for the problem, but that's not actually possible, 
   since we would have to be able to run an application on the _target_ 
   system to test poll() behavior.
2) Always include poll.o in the build, but it will be empty if AST_POLL_COMPAT
   is not defined.
3) Change uses of poll() throughout the source tree to ast_poll().  I feel 
   that it is good practice to give the API call a new name when we are 
   changing its behavior and not using the system version directly in all cases.
   So, normally, ast_poll() is just redefined to poll().  On systems where 
   AST_POLL_COMPAT is defined, ast_poll() is redefined to ast_internal_poll().
4) Change poll() in main/poll.c to be ast_internal_poll().
It's worth noting that any code that still uses poll() directly will work fine 
(if they worked fine before).  So, for example, out of tree modules that are 
using poll() will not stop working or anything.  However, for modules to work 
properly on Mac OSX, ast_poll() needs to be used.
(closes issue #13404)
Reported by: agalbraith
Tested by: russell, vadim
http://reviewboard.digium.com/r/198/
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@182847 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-03-18 02:28:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											res  =  ast_poll ( pfds ,  max ,  kbrms ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-20 22:45:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ! res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												rms  - =  kbrms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  while  ( ! res  & &  ( rms  >  0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 182810 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r182810 | russell | 2009-03-17 21:09:13 -0500 (Tue, 17 Mar 2009) | 44 lines
Fix cases where the internal poll() was not being used when it needed to be.
We have seen a number of problems caused by poll() not working properly on 
Mac OSX.  If you search around, you'll find a number of references to using 
select() instead of poll() to work around these issues.  In Asterisk, we've 
had poll.c which implements poll() using select() internally.  However, we 
were still getting reports of problems.
vadim investigated a bit and realized that at least on his system, even 
though we were compiling in poll.o, the system poll() was still being used.  
So, the primary purpose of this patch is to ensure that we're using the 
internal poll() when we want it to be used.
The changes are:
1) Remove logic for when internal poll should be used from the Makefile.  
   Instead, put it in the configure script.  The logic in the configure 
   script is the same as it was in the Makefile.  Ideally, we would have 
   a functionality test for the problem, but that's not actually possible, 
   since we would have to be able to run an application on the _target_ 
   system to test poll() behavior.
2) Always include poll.o in the build, but it will be empty if AST_POLL_COMPAT
   is not defined.
3) Change uses of poll() throughout the source tree to ast_poll().  I feel 
   that it is good practice to give the API call a new name when we are 
   changing its behavior and not using the system version directly in all cases.
   So, normally, ast_poll() is just redefined to poll().  On systems where 
   AST_POLL_COMPAT is defined, ast_poll() is redefined to ast_internal_poll().
4) Change poll() in main/poll.c to be ast_internal_poll().
It's worth noting that any code that still uses poll() directly will work fine 
(if they worked fine before).  So, for example, out of tree modules that are 
using poll() will not stop working or anything.  However, for modules to work 
properly on Mac OSX, ast_poll() needs to be used.
(closes issue #13404)
Reported by: agalbraith
Tested by: russell, vadim
http://reviewboard.digium.com/r/198/
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@182847 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-03-18 02:28:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  ast_poll ( pfds ,  max ,  rms ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-20 22:45:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( x  =  0 ;  x  <  n ;  x + + ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_clear_flag ( c [ x ] ,  AST_FLAG_BLOCKING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( res  <  0 )  {  /* Simulate a timeout if we were interrupted */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 08:02:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( errno  ! =  EINTR ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* ms  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ast_tvzero ( whentohangup ) )  {    /* if we have a timeout, check who expired */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										now  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										for  ( x  =  0 ;  x  <  n ;  x + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ! ast_tvzero ( c [ x ] - > whentohangup )  & &  ast_tvcmp ( c [ x ] - > whentohangup ,  now )  < =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												c [ x ] - > _softhangup  | =  AST_SOFTHANGUP_TIMEOUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( winner  = =  NULL ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													winner  =  c [ x ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( res  = =  0 )  {  /* no fd ready, reset timeout and done */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* ms  =  0 ; 	/* XXX use 0 since we may not have an exact timeout. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  winner ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Then  check  if  any  channel  or  fd  has  a  pending  event . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Remember  to  check  channels  first  and  fds  last ,  as  they 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  must  have  priority  on  setting  ' winner ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( x  =  0 ;  x  <  max ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  pfds [ x ] . revents ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( res  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( fdmap [ x ] . chan  > =  0 )  { 	/* this is a channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											winner  =  c [ fdmap [ x ] . chan ] ; 	/* override previous winners */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( res  &  POLLPRI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_set_flag ( winner ,  AST_FLAG_EXCEPTION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_clear_flag ( winner ,  AST_FLAG_EXCEPTION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											winner - > fdno  =  fdmap [ x ] . fdno ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 			/* this is an fd */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( outfd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												* outfd  =  pfds [ x ] . fd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( exception ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												* exception  =  ( res  &  POLLPRI )  ?  - 1  :  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											winner  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-25 20:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( * ms  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 23:00:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										* ms  - =  ast_tvdiff_ms ( ast_tvnow ( ) ,  start ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( * ms  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-25 20:42:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											* ms  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									return  winner ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef HAVE_EPOLL 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  struct  ast_channel  * ast_waitfor_nandfds_simple ( struct  ast_channel  * chan ,  int  * ms ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  timeval  start  =  {  0  ,  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  epoll_event  ev [ 1 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									long  diff ,  rms  =  * ms ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * winner  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_epoll_data  * aed  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* See if this channel needs to be masqueraded */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan - > masq  & &  ast_do_masquerade ( chan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Failed to perform masquerade on %s \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* ms  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Figure out their timeout */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ast_tvzero ( chan - > whentohangup ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ( diff  =  ast_tvdiff_ms ( chan - > whentohangup ,  ast_tvnow ( ) ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* They should already be hungup! */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											chan - > _softhangup  | =  AST_SOFTHANGUP_TIMEOUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* If this value is smaller then the current one... make it priority */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( rms  >  diff ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											rms  =  diff ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Time to make this channel block... */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									CHECK_BLOCKING ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( * ms  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										start  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* We don't have to add any file descriptors... they are already added, we just have to wait! */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									res  =  epoll_wait ( chan - > epfd ,  ev ,  1 ,  rms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Stop blocking */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_clear_flag ( chan ,  AST_FLAG_BLOCKING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Simulate a timeout if we were interrupted */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( errno  ! =  EINTR ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* ms  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* If this channel has a timeout see if it expired */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ast_tvzero ( chan - > whentohangup ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ast_tvdiff_ms ( ast_tvnow ( ) ,  chan - > whentohangup )  > =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											chan - > _softhangup  | =  AST_SOFTHANGUP_TIMEOUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											winner  =  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* No fd ready, reset timeout and be done for now */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* ms  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  winner ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* See what events are pending */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									aed  =  ev [ 0 ] . data . ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									chan - > fdno  =  aed - > which ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ev [ 0 ] . events  &  EPOLLPRI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_set_flag ( chan ,  AST_FLAG_EXCEPTION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_clear_flag ( chan ,  AST_FLAG_EXCEPTION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( * ms  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* ms  - =  ast_tvdiff_ms ( ast_tvnow ( ) ,  start ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( * ms  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* ms  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  struct  ast_channel  * ast_waitfor_nandfds_complex ( struct  ast_channel  * * c ,  int  n ,  int  * ms ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  timeval  start  =  {  0  ,  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res  =  0 ,  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  epoll_event  ev [ 25 ]  =  {  {  0 ,  }  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  timeval  now  =  {  0 ,  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									long  whentohangup  =  0 ,  diff  =  0 ,  rms  =  * ms ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * winner  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( i  =  0 ;  i  <  n ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( c [ i ] - > masq  & &  ast_do_masquerade ( c [ i ] ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Masquerade failed \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* ms  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_lock ( c [ i ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! ast_tvzero ( c [ i ] - > whentohangup ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( whentohangup  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												now  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ( diff  =  ast_tvdiff_ms ( c [ i ] - > whentohangup ,  now ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												c [ i ] - > _softhangup  | =  AST_SOFTHANGUP_TIMEOUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_channel_unlock ( c [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  c [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ! whentohangup  | |  whentohangup  >  diff ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												whentohangup  =  diff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( c [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										CHECK_BLOCKING ( c [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									rms  =  * ms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( whentohangup )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										rms  =  whentohangup ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( * ms  > =  0  & &  * ms  <  rms ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											rms  =  * ms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( * ms  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										start  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									res  =  epoll_wait ( c [ 0 ] - > epfd ,  ev ,  25 ,  rms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( i  =  0 ;  i  <  n ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_clear_flag ( c [ i ] ,  AST_FLAG_BLOCKING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( errno  ! =  EINTR ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* ms  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( whentohangup )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										now  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										for  ( i  =  0 ;  i  <  n ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-01 23:06:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ! ast_tvzero ( c [ i ] - > whentohangup )  & &  ast_tvdiff_ms ( now ,  c [ i ] - > whentohangup )  > =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												c [ i ] - > _softhangup  | =  AST_SOFTHANGUP_TIMEOUT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( ! winner ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													winner  =  c [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* ms  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  winner ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 04:37:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( i  =  0 ;  i  <  res ;  i + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										struct  ast_epoll_data  * aed  =  ev [ i ] . data . ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! ev [ i ] . events  | |  ! aed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										winner  =  aed - > chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ev [ i ] . events  &  EPOLLPRI ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_set_flag ( winner ,  AST_FLAG_EXCEPTION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_clear_flag ( winner ,  AST_FLAG_EXCEPTION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										winner - > fdno  =  aed - > which ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( * ms  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* ms  - =  ast_tvdiff_ms ( ast_tvnow ( ) ,  start ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( * ms  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* ms  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  winner ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_waitfor_nandfds ( struct  ast_channel  * * c ,  int  n ,  int  * fds ,  int  nfds , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													int  * exception ,  int  * outfd ,  int  * ms ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-14 14:17:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Clear all provided values in one place. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( outfd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* outfd  =  - 99999 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( exception ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* exception  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* If no epoll file descriptor is available resort to classic nandfds */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! n  | |  nfds  | |  c [ 0 ] - > epfd  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ast_waitfor_nandfds_classic ( c ,  n ,  fds ,  nfds ,  exception ,  outfd ,  ms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else  if  ( ! nfds  & &  n  = =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ast_waitfor_nandfds_simple ( c [ 0 ] ,  ms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ast_waitfor_nandfds_complex ( c ,  n ,  ms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_waitfor_n ( struct  ast_channel  * * c ,  int  n ,  int  * ms ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ast_waitfor_nandfds ( c ,  n ,  NULL ,  0 ,  NULL ,  NULL ,  ms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								int  ast_waitfor ( struct  ast_channel  * c ,  int  ms ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 20:47:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  oldms  =  ms ; 	/* -1 if no timeout */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_waitfor_nandfds ( & c ,  1 ,  NULL ,  0 ,  NULL ,  NULL ,  & ms ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( ms  <  0 )  & &  ( oldms  <  0 ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ms  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ms ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 20:47:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* XXX never to be called with ms = -1 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-05 15:04:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_waitfordigit ( struct  ast_channel  * c ,  int  ms ) 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 07:53:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_waitfordigit_full ( c ,  ms ,  - 1 ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 12:45:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_settimeout ( struct  ast_channel  * c ,  unsigned  int  rate ,  int  ( * func ) ( const  void  * data ) ,  void  * data ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-05-12 04:23:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 12:45:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-26 15:37:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									unsigned  int  real_rate  =  rate ,  max_rate ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 12:45:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-02 23:00:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 12:45:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( c - > timingfd  = =  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-02 23:00:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 12:45:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! func )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										rate  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										data  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-05-12 04:23:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 12:45:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-27 19:10:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( rate  & &  rate  >  ( max_rate  =  ast_timer_get_max_rate ( c - > timer ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-26 15:37:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										real_rate  =  max_rate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_debug ( 1 ,  " Scheduling timer at (%u requested / %u actual) timer ticks per second \n " ,  rate ,  real_rate ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 12:45:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-27 19:10:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									res  =  ast_timer_set_rate ( c - > timer ,  real_rate ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 12:45:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									c - > timingfunc  =  func ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									c - > timingdata  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-02 23:00:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-05-12 04:23:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-05 15:04:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_waitfordigit_full ( struct  ast_channel  * c ,  int  ms ,  int  audiofd ,  int  cmdfd ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Stop if we're a zombie or need a soft hangup */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( c ,  AST_FLAG_ZOMBIE )  | |  ast_check_hangup ( c ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-04 13:47:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_set_flag ( c ,  AST_FLAG_END_DTMF_ONLY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Wait for a digit, no more than ms milliseconds total. */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-14 13:46:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 08:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									while  ( ms )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										struct  ast_channel  * rchan ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-14 13:46:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										int  outfd = - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 08:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-22 01:40:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										errno  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-12 16:25:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										rchan  =  ast_waitfor_nandfds ( & c ,  1 ,  & cmdfd ,  ( cmdfd  >  - 1 )  ?  1  :  0 ,  NULL ,  & outfd ,  & ms ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-14 13:46:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 08:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! rchan  & &  outfd  <  0  & &  ms )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-22 01:40:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( errno  = =  0  | |  errno  = =  EINTR ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-22 22:44:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-12 16:25:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Wait failed (%s) \n " ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-04 13:47:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_clear_flag ( c ,  AST_FLAG_END_DTMF_ONLY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-12 16:25:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  if  ( outfd  >  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* The FD we were watching has something waiting */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-14 13:46:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " The FD we were waiting for has something waiting. Waitfordigit returning numeric 1 \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-04 13:47:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_clear_flag ( c ,  AST_FLAG_END_DTMF_ONLY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-12 16:25:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										}  else  if  ( rchan )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 08:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											struct  ast_frame  * f  =  ast_read ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ! f ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-12 16:25:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-01-23 00:11:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											switch  ( f - > frametype )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-12 17:17:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											case  AST_FRAME_DTMF_BEGIN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  AST_FRAME_DTMF_END : 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												res  =  f - > subclass . integer ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-04 13:47:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_clear_flag ( c ,  AST_FLAG_END_DTMF_ONLY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-12 16:25:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  AST_FRAME_CONTROL : 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												switch  ( f - > subclass . integer )  { 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-12 16:25:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_HANGUP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-04 13:47:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_clear_flag ( c ,  AST_FLAG_END_DTMF_ONLY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-12 16:25:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_RINGING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_ANSWER : 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-07 19:33:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_SRCUPDATE : 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-12 22:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_SRCCHANGE : 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_CONNECTED_LINE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_REDIRECTING : 
							 
						 
					
						
							
								
									
										
										
										
											2011-10-14 16:33:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_UPDATE_RTP_PEER : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-26 21:53:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  - 1 : 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-12 16:25:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													/* Unimportant */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												default : 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_log ( LOG_WARNING ,  " Unexpected control subclass '%d' \n " ,  f - > subclass . integer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-01 16:34:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-12 16:25:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-01 16:34:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-12 16:25:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											case  AST_FRAME_VOICE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* Write audio if appropriate */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-02 18:52:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( audiofd  >  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( write ( audiofd ,  f - > data . ptr ,  f - > datalen )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														ast_log ( LOG_WARNING ,  " write() failed: %s \n " ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* Ignore */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-12 16:25:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-04 13:47:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_clear_flag ( c ,  AST_FLAG_END_DTMF_ONLY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-15 23:48:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  0 ;  /* Time is up */ 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  send_dtmf_event ( struct  ast_channel  * chan ,  const  char  * direction ,  const  char  digit ,  const  char  * begin ,  const  char  * end ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-10 23:55:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_manager_event ( chan ,  EVENT_FLAG_DTMF , 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-10 23:55:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											" DTMF " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" Channel: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" Uniqueid: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" Digit: %c \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" Direction: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" Begin: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" End: %s \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											chan - > name ,  chan - > uniqueid ,  digit ,  direction ,  begin ,  end ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-27 17:34:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  ast_read_generator_actions ( struct  ast_channel  * chan ,  struct  ast_frame  * f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-30 16:56:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > generator  & &  chan - > generator - > generate  & &  chan - > generatordata  & &   ! ast_internal_timing_enabled ( chan ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-27 17:34:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										void  * tmp  =  chan - > generatordata ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-09-30 16:56:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										int  ( * generate ) ( struct  ast_channel  * chan ,  void  * tmp ,  int  datalen ,  int  samples )  =  chan - > generator - > generate ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-27 17:34:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										int  res ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Add some fixes that I made in regards to wideband codec handling to get
G.722 music on hold working for me.
(issue #12164, reported by milazzo and jsmith, patches by me)
res/res_musiconhold.c:
 - I moved a single line so that the sample queue update happened before
   ast_write().  The reason that this was a bug is that the G.722 frame
   originally says it has 320 samples in it (which is correct).  However,
   when the frame is written to a channel that uses RTP, main/rtp.c modifies
   the frame to cut the number of samples in half before it sends it on
   the wire.  This is to account for the stupid incorrect G.722 spec that
   makes it so we have to lie about the number of samples with RTP.  I should
   probably go and re-work the RTP code so it doesn't modify the frame so
   that a bug like this won't happen in the future.  However, this change to
   MOH is harmless.
main/channel.c:
 - I made two fixes in regards to generator timing.  Generators use samples
   for timing.  However, this code assumed 8 kHz samples.  In one case, it was
   a hard coded 160 samples, that is now written as the sample rate / 50.  The
   other place was dealing with timing a generator based on frames coming from
   the other direction.  However, that would have only worked if the sample
   rates for the formats in both directions were the same.  The code now takes
   into account that the sample rates may differ, and scales the generator
   samples accordingly.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@110268 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-03-20 17:41:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										int  samples ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-27 17:34:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( chan - > timingfunc )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-15 15:20:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_debug ( 1 ,  " Generator got voice, switching to phase locked mode \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-27 17:34:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_settimeout ( chan ,  0 ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > generatordata  =  NULL ;      /* reset, to let writes go through */ 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Add some fixes that I made in regards to wideband codec handling to get
G.722 music on hold working for me.
(issue #12164, reported by milazzo and jsmith, patches by me)
res/res_musiconhold.c:
 - I moved a single line so that the sample queue update happened before
   ast_write().  The reason that this was a bug is that the G.722 frame
   originally says it has 320 samples in it (which is correct).  However,
   when the frame is written to a channel that uses RTP, main/rtp.c modifies
   the frame to cut the number of samples in half before it sends it on
   the wire.  This is to account for the stupid incorrect G.722 spec that
   makes it so we have to lie about the number of samples with RTP.  I should
   probably go and re-work the RTP code so it doesn't modify the frame so
   that a bug like this won't happen in the future.  However, this change to
   MOH is harmless.
main/channel.c:
 - I made two fixes in regards to generator timing.  Generators use samples
   for timing.  However, this code assumed 8 kHz samples.  In one case, it was
   a hard coded 160 samples, that is now written as the sample rate / 50.  The
   other place was dealing with timing a generator based on frames coming from
   the other direction.  However, that would have only worked if the sample
   rates for the formats in both directions were the same.  The code now takes
   into account that the sample rates may differ, and scales the generator
   samples accordingly.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@110268 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-03-20 17:41:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( f - > subclass . codec  ! =  chan - > writeformat )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Add some fixes that I made in regards to wideband codec handling to get
G.722 music on hold working for me.
(issue #12164, reported by milazzo and jsmith, patches by me)
res/res_musiconhold.c:
 - I moved a single line so that the sample queue update happened before
   ast_write().  The reason that this was a bug is that the G.722 frame
   originally says it has 320 samples in it (which is correct).  However,
   when the frame is written to a channel that uses RTP, main/rtp.c modifies
   the frame to cut the number of samples in half before it sends it on
   the wire.  This is to account for the stupid incorrect G.722 spec that
   makes it so we have to lie about the number of samples with RTP.  I should
   probably go and re-work the RTP code so it doesn't modify the frame so
   that a bug like this won't happen in the future.  However, this change to
   MOH is harmless.
main/channel.c:
 - I made two fixes in regards to generator timing.  Generators use samples
   for timing.  However, this code assumed 8 kHz samples.  In one case, it was
   a hard coded 160 samples, that is now written as the sample rate / 50.  The
   other place was dealing with timing a generator based on frames coming from
   the other direction.  However, that would have only worked if the sample
   rates for the formats in both directions were the same.  The code now takes
   into account that the sample rates may differ, and scales the generator
   samples accordingly.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@110268 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-03-20 17:41:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											float  factor ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											factor  =  ( ( float )  ast_format_rate ( chan - > writeformat ) )  /  ( ( float )  ast_format_rate ( f - > subclass . codec ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Add some fixes that I made in regards to wideband codec handling to get
G.722 music on hold working for me.
(issue #12164, reported by milazzo and jsmith, patches by me)
res/res_musiconhold.c:
 - I moved a single line so that the sample queue update happened before
   ast_write().  The reason that this was a bug is that the G.722 frame
   originally says it has 320 samples in it (which is correct).  However,
   when the frame is written to a channel that uses RTP, main/rtp.c modifies
   the frame to cut the number of samples in half before it sends it on
   the wire.  This is to account for the stupid incorrect G.722 spec that
   makes it so we have to lie about the number of samples with RTP.  I should
   probably go and re-work the RTP code so it doesn't modify the frame so
   that a bug like this won't happen in the future.  However, this change to
   MOH is harmless.
main/channel.c:
 - I made two fixes in regards to generator timing.  Generators use samples
   for timing.  However, this code assumed 8 kHz samples.  In one case, it was
   a hard coded 160 samples, that is now written as the sample rate / 50.  The
   other place was dealing with timing a generator based on frames coming from
   the other direction.  However, that would have only worked if the sample
   rates for the formats in both directions were the same.  The code now takes
   into account that the sample rates may differ, and scales the generator
   samples accordingly.
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@110268 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2008-03-20 17:41:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											samples  =  ( int )  (  ( ( float )  f - > samples )  *  factor  ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											samples  =  f - > samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-14 15:01:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
									
										
										
										
											2008-04-07 16:12:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* This unlock is here based on two assumptions that hold true at this point in the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  code .  1 )  this  function  is  only  called  from  within  __ast_read ( )  and  2 )  all  generators 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  call  ast_write ( )  in  their  generate  callback . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  The  reason  this  is  added  is  so  that  when  ast_write  is  called ,  the  lock  that  occurs  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  there  will  not  recursively  lock  the  channel .  Doing  this  will  cause  intended  deadlock  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  avoidance  not  to  work  in  deeper  functions 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-22 20:25:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  generate ( chan ,  tmp ,  f - > datalen ,  samples ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-07 16:12:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-27 17:34:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > generatordata  =  tmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-15 15:20:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_debug ( 1 ,  " Auto-deactivating generator \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-27 17:34:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_deactivate_generator ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( f - > frametype  = =  AST_FRAME_CNG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( chan - > generator  & &  ! chan - > timingfunc  & &  ( chan - > timingfd  >  - 1 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-15 15:20:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_debug ( 1 ,  " Generator got CNG, switching to timed mode \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-13 12:45:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_settimeout ( chan ,  50 ,  generator_force ,  chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-27 17:34:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  inline  void  queue_dtmf_readq ( struct  ast_channel  * chan ,  struct  ast_frame  * f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_frame  * fr  =  & chan - > dtmff ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									fr - > frametype  =  AST_FRAME_DTMF_END ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									fr - > subclass . integer  =  f - > subclass . integer ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									fr - > len  =  f - > len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* The only time this function will be called is for a frame that just came
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  out  of  the  channel  driver .   So ,  we  want  to  stick  it  on  the  tail  of  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  readq .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_queue_frame ( chan ,  fr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Determine  whether  or  not  we  should  ignore  DTMF  in  the  readq 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  should_skip_dtmf ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( chan ,  AST_FLAG_DEFER_DTMF  |  AST_FLAG_EMULATE_DTMF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* We're in the middle of emulating a digit, or DTMF has been
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  explicitly  deferred .   Skip  this  digit ,  then .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_tvzero ( chan - > dtmf_tv )  & &  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_tvdiff_ms ( ast_tvnow ( ) ,  chan - > dtmf_tv )  <  AST_MIN_DTMF_GAP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* We're not in the middle of a digit, but it hasn't been long enough
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  since  the  last  digit ,  so  we ' ll  have  to  skip  DTMF  for  now .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-02-16 17:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  calculates  the  number  of  samples  to  jump  forward  with  in  a  monitor  stream . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ note  When  using  ast_seekstream ( )  with  the  read  and  write  streams  of  a  monitor , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  the  number  of  samples  to  seek  forward  must  be  of  the  same  sample  rate  as  the  stream 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  or  else  the  jump  will  not  be  calculated  correctly . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ retval  number  of  samples  to  seek  forward  after  rate  conversion . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  inline  int  calc_monitor_jump ( int  samples ,  int  sample_rate ,  int  seek_rate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  diff  =  sample_rate  -  seek_rate ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( diff  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										samples  =  samples  /  ( float )  ( sample_rate  /  seek_rate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( diff  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										samples  =  samples  *  ( float )  ( seek_rate  /  sample_rate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-20 13:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  struct  ast_frame  * __ast_read ( struct  ast_channel  * chan ,  int  dropaudio ) 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 13:27:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_frame  * f  =  NULL ; 	/* the return value */ 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  blah ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 19:07:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  prestate ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  cause  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 13:27:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 17:41:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* this function is very long so make sure there is only one return
 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-05 23:31:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									 *  point  at  the  end  ( there  are  only  two  exceptions  to  this ) . 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 17:41:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-05 23:31:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > masq )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ast_do_masquerade ( chan ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Failed to perform masquerade \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										else 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-31 17:18:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											f  =   & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  f ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* if here, no masq has happened, lock the channel and proceed */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-20 14:05:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Stop if we're a zombie or need a soft hangup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( chan ,  AST_FLAG_ZOMBIE )  | |  ast_check_hangup ( chan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( chan - > generator ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_deactivate_generator ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:01:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  It  is  possible  for  chan - > _softhangup  to  be  set  and  there 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  still  be  control  frames  that  need  to  be  read .   Instead  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  just  going  to  ' done '  in  the  case  of  ast_check_hangup ( ) ,  we 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  need  to  queue  the  end - of - Q  frame  so  that  it  can  mark  the  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  of  the  read  queue .   If  there  are  frames  to  be  read , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  ast_queue_control ( )  will  be  called  repeatedly ,  but  will  only 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  queue  the  first  end - of - Q  frame . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( chan - > _softhangup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_queue_control ( chan ,  AST_CONTROL_END_OF_Q ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:01:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											goto  done ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-13 16:31:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 15:27:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef AST_DEVMODE 
 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-13 16:31:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  The  ast_waitfor ( )  code  records  which  of  the  channel ' s  file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  descriptors  reported  that  data  is  available .   In  theory , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  ast_read ( )  should  only  be  called  after  ast_waitfor ( )  reports 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  that  a  channel  has  data  available  for  reading .   However , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  there  still  may  be  some  edge  cases  throughout  the  code  where 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  ast_read ( )  is  called  improperly .   This  can  potentially  cause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  problems ,  so  if  this  is  a  developer  build ,  make  a  lot  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  noise  if  this  happens  so  that  it  can  be  addressed . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  One  of  the  potential  problems  is  blocking  on  a  dead  channel . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( chan - > fdno  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_ERROR , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												" ast_read() on chan '%s' called with no recorded file descriptor. \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-20 16:36:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-13 16:31:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-20 16:36:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									prestate  =  chan - > _state ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Read and ignore anything on the alertpipe, but read only
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									   one  sizeof ( blah )  per  frame  that  we  send  from  it  */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-12 15:14:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > alertpipe [ 0 ]  >  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  flags  =  fcntl ( chan - > alertpipe [ 0 ] ,  F_GETFL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* For some odd reason, the alertpipe occasionally loses nonblocking status,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  which  immediately  causes  a  deadlock  scenario .   Detect  and  prevent  this .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ( flags  &  O_NONBLOCK )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_ERROR ,  " Alertpipe on channel %s lost O_NONBLOCK?!! \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( fcntl ( chan - > alertpipe [ 0 ] ,  F_SETFL ,  flags  |  O_NONBLOCK )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Unable to set alertpipe nonblocking! (%d: %s) \n " ,  errno ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												goto  done ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-02 18:52:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( read ( chan - > alertpipe [ 0 ] ,  & blah ,  sizeof ( blah ) )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-05 16:11:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( errno  ! =  EINTR  & &  errno  ! =  EAGAIN ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " read() failed: %s \n " ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-02 18:52:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-12 15:14:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 17:41:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-06-16 12:48:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > timingfd  >  - 1  & &  chan - > fdno  = =  AST_TIMING_FD )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 21:22:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										enum  ast_timer_event  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 13:27:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_clear_flag ( chan ,  AST_FLAG_EXCEPTION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-16 12:48:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-27 19:10:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  ast_timer_get_event ( chan - > timer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-16 12:48:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_TIMING_EVENT_EXPIRED : 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-27 19:10:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_timer_ack ( chan - > timer ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-16 12:48:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 13:27:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( chan - > timingfunc )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 17:21:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												/* save a copy of func/data before unlocking the channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												int  ( * func ) ( const  void  * )  =  chan - > timingfunc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												void  * data  =  chan - > timingdata ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:47:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												chan - > fdno  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 17:21:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												func ( data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-03-19 04:23:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-27 19:10:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_timer_set_rate ( chan - > timer ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:47:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												chan - > fdno  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 17:21:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-03-19 04:23:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-16 12:48:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 17:41:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* cannot 'goto done' because the channel is already unlocked */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-31 17:18:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-16 12:48:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_TIMING_EVENT_CONTINUOUS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( AST_LIST_EMPTY ( & chan - > readq )  | |  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												! AST_LIST_NEXT ( AST_LIST_FIRST ( & chan - > readq ) ,  frame_list ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-27 19:10:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_timer_disable_continuous ( chan - > timer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-16 12:48:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( chan - > fds [ AST_GENERATOR_FD ]  >  - 1  & &  chan - > fdno  = =  AST_GENERATOR_FD )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 17:41:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* if the AST_GENERATOR_FD is set, call the generator with args
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  set  to  - 1  so  it  can  do  whatever  it  needs  to . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										void  * tmp  =  chan - > generatordata ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > generatordata  =  NULL ;      /* reset to let ast_write get through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > generator - > generate ( chan ,  tmp ,  - 1 ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > generatordata  =  tmp ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 17:41:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:47:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > fdno  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 17:41:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										goto  done ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Check for pending read queue */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 20:50:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! AST_LIST_EMPTY ( & chan - > readq ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										int  skip_dtmf  =  should_skip_dtmf ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_LIST_TRAVERSE_SAFE_BEGIN ( & chan - > readq ,  f ,  frame_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* We have to be picky about which frame we pull off of the readq because
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  there  are  cases  where  we  want  to  leave  DTMF  frames  on  the  queue  until 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  some  later  time .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  (  ( f - > frametype  = =  AST_FRAME_DTMF_BEGIN  | |  f - > frametype  = =  AST_FRAME_DTMF_END )  & &  skip_dtmf )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											AST_LIST_REMOVE_CURRENT ( frame_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-10 03:55:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_LIST_TRAVERSE_SAFE_END ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! f )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* There were no acceptable frames on the readq. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( chan - > alertpipe [ 0 ]  >  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												int  poke  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* Restore the state of the alertpipe since we aren't ready for any
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 *  of  the  frames  in  the  readq .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( write ( chan - > alertpipe [ 1 ] ,  & poke ,  sizeof ( poke ) )  ! =  sizeof ( poke ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_log ( LOG_ERROR ,  " Failed to write to alertpipe: %s \n " ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* Interpret hangup and end-of-Q frames to return NULL */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-09 07:51:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* XXX why not the same for frames from the channel ? */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( f - > frametype  = =  AST_FRAME_CONTROL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											switch  ( f - > subclass . integer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  AST_CONTROL_HANGUP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												chan - > _softhangup  | =  AST_SOFTHANGUP_DEV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												cause  =  f - > data . uint32 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* Fall through */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  AST_CONTROL_END_OF_Q : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												f  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2003-11-07 03:48:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > blocker  =  pthread_self ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ast_test_flag ( chan ,  AST_FLAG_EXCEPTION ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( chan - > tech - > exception ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												f  =  chan - > tech - > exception ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Exception flag set on '%s', but no exception handler \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-31 17:18:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* Clear the exception flag */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_clear_flag ( chan ,  AST_FLAG_EXCEPTION ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-13 18:09:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										}  else  if  ( chan - > tech  & &  chan - > tech - > read ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 13:58:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											f  =  chan - > tech - > read ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " No read routine on channel %s \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 16:47:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 14:40:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									 *  Reset  the  recorded  file  descriptor  that  triggered  this  read  so  that  we  can 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  easily  detect  when  ast_read ( )  is  called  without  properly  using  ast_waitfor ( ) . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									chan - > fdno  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Perform the framehook read event here. After the frame enters the framehook list
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  there  is  no  telling  what  will  happen ,  < insert  mad  scientist  laugh  here > ! ! !  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									f  =  ast_framehook_list_read_event ( chan - > framehooks ,  f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( f )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										struct  ast_frame  * readq_tail  =  AST_LIST_LAST ( & chan - > readq ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										struct  ast_control_read_action_payload  * read_action_payload ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										struct  ast_party_connected_line  connected ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* if the channel driver returned more than one frame, stuff the excess
 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										   into  the  readq  for  the  next  ast_read  call 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										*/ 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 20:50:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( AST_LIST_NEXT ( f ,  frame_list ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_queue_frame ( chan ,  AST_LIST_NEXT ( f ,  frame_list ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_frfree ( AST_LIST_NEXT ( f ,  frame_list ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-29 20:50:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											AST_LIST_NEXT ( f ,  frame_list )  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										switch  ( f - > frametype )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_FRAME_CONTROL : 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( f - > subclass . integer  = =  AST_CONTROL_ANSWER )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-09 15:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( ! ast_test_flag ( chan ,  AST_FLAG_OUTGOING ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_debug ( 1 ,  " Ignoring answer on an inbound call! \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-16 20:08:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-09 15:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-14 18:04:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												}  else  if  ( prestate  = =  AST_STATE_UP  & &  ast_bridged_channel ( chan ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_debug ( 1 ,  " Dropping duplicate answer! \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-16 20:08:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-31 17:18:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-09 15:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													/* Answer the CDR */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_setstate ( chan ,  AST_STATE_UP ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													/* removed a call to ast_cdr_answer(chan->cdr) from here. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_cel_report_event ( chan ,  AST_CEL_ANSWER ,  NULL ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											}  else  if  ( f - > subclass . integer  = =  AST_CONTROL_READ_ACTION )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												read_action_payload  =  f - > data . ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												switch  ( read_action_payload - > action )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO : 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-25 16:23:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_party_connected_line_init ( & connected ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_party_connected_line_copy ( & connected ,  & chan - > connected ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													if  ( ast_connected_line_parse_data ( read_action_payload - > payload , 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-25 16:23:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														read_action_payload - > payload_size ,  & connected ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														ast_party_connected_line_free ( & connected ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( ast_channel_connected_line_macro ( NULL ,  chan ,  & connected ,  1 ,  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														ast_indicate_data ( chan ,  AST_CONTROL_CONNECTED_LINE , 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-25 16:23:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
															read_action_payload - > payload , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															read_action_payload - > payload_size ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-25 16:23:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_party_connected_line_free ( & connected ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_FRAME_DTMF_END : 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											send_dtmf_event ( chan ,  " Received " ,  f - > subclass . integer ,  " No " ,  " Yes " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_DTMF ,  " DTMF end '%c' received on %s, duration %ld ms \n " ,  f - > subclass . integer ,  chan - > name ,  f - > len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* Queue it up if DTMF is deferred, or if DTMF emulation is forced. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ast_test_flag ( chan ,  AST_FLAG_DEFER_DTMF )  | |  ast_test_flag ( chan ,  AST_FLAG_EMULATE_DTMF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												queue_dtmf_readq ( chan ,  f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-16 20:08:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-31 17:18:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											}  else  if  ( ! ast_test_flag ( chan ,  AST_FLAG_IN_DTMF  |  AST_FLAG_END_DTMF_ONLY ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-24 19:03:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( ! ast_tvzero ( chan - > dtmf_tv )  & &  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												    ast_tvdiff_ms ( ast_tvnow ( ) ,  chan - > dtmf_tv )  <  AST_MIN_DTMF_GAP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													/* If it hasn't been long enough, defer this digit */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 13:55:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													queue_dtmf_readq ( chan ,  f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-24 19:03:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													/* There was no begin, turn this into a begin and send the end later */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													f - > frametype  =  AST_FRAME_DTMF_BEGIN ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_set_flag ( chan ,  AST_FLAG_EMULATE_DTMF ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													chan - > emulate_dtmf_digit  =  f - > subclass . integer ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-24 19:03:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													chan - > dtmf_tv  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 62942 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r62942 | russell | 2007-05-03 10:23:13 -0500 (Thu, 03 May 2007) | 17 lines
Fix YADB (Yet Another DTMF Bug) ((C) Russell Bryant, 2007, TM, Patent Pending).
This set of changes came from a debugging session I had with Dwayne Hubbard.
When he called into his home FXO, ran the Echo application, and pressed a
digit, the digit would be echoed back and would never end.  This is fixed,
along with a couple other little improvements.
* When chan_zap is in the middle of playing a digit to a channel, it feeds
  back null frames, not voice frames.  So, I have modified ast_read to check
  the timing on emulated DTMF when it receives null frames, in addition to
  where it was doing this on voice frames.
* Make a tweak to setting the duration on emulated DTMF digits.  If there was
  no duration specified, it set it to be the minimum, instead of the default.
* Instead of timing the emulated digits off of the number of samples in audio
  frames that pass through, just use time values.  Now there is no code in this
  section that assumes 8kHz audio.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@62943 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-05-03 15:23:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													if  ( f - > len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														if  ( f - > len  >  AST_MIN_DTMF_DURATION ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															chan - > emulate_dtmf_duration  =  f - > len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														else  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															chan - > emulate_dtmf_duration  =  AST_MIN_DTMF_DURATION ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														chan - > emulate_dtmf_duration  =  AST_DEFAULT_EMULATE_DTMF_DURATION ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_log ( LOG_DTMF ,  " DTMF begin emulation of '%c' with duration %u queued on %s \n " ,  f - > subclass . integer ,  chan - > emulate_dtmf_duration ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-24 19:03:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-06 22:34:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( chan - > audiohooks )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													struct  ast_frame  * old_frame  =  f ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-26 18:19:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 *  \ todo  XXX  It  is  possible  to  write  a  digit  to  the  audiohook  twice 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 *  if  the  digit  was  originally  read  while  the  channel  was  in  autoservice .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 19:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f  =  ast_audiohook_write_list ( chan ,  chan - > audiohooks ,  AST_AUDIOHOOK_DIRECTION_READ ,  f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-06 22:34:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													if  ( old_frame  ! =  f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														ast_frfree ( old_frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-24 19:03:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												struct  timeval  now  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 23:20:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( ast_test_flag ( chan ,  AST_FLAG_IN_DTMF ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_log ( LOG_DTMF ,  " DTMF end accepted with begin '%c' on %s \n " ,  f - > subclass . integer ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 23:20:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_clear_flag ( chan ,  AST_FLAG_IN_DTMF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( ! f - > len ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														f - > len  =  ast_tvdiff_ms ( now ,  chan - > dtmf_tv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-16 17:30:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													/* detect tones that were received on
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 *  the  wire  with  durations  shorter  than 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 *  AST_MIN_DTMF_DURATION  and  set  f - > len 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 *  to  the  actual  duration  of  the  DTMF 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 *  frames  on  the  wire .   This  will  cause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 *  dtmf  emulation  to  be  triggered  later 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 *  on . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( ast_tvdiff_ms ( now ,  chan - > dtmf_tv )  <  AST_MIN_DTMF_DURATION )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														f - > len  =  ast_tvdiff_ms ( now ,  chan - > dtmf_tv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-16 18:05:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														ast_log ( LOG_DTMF ,  " DTMF end '%c' detected to have actual duration %ld on the wire, emulation will be triggered on %s \n " ,  f - > subclass . integer ,  f - > len ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-16 17:30:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-06 21:43:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												}  else  if  ( ! f - > len )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_log ( LOG_DTMF ,  " DTMF end accepted without begin '%c' on %s \n " ,  f - > subclass . integer ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 23:20:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f - > len  =  AST_MIN_DTMF_DURATION ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-06 21:43:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-09 16:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( f - > len  <  AST_MIN_DTMF_DURATION  & &  ! ast_test_flag ( chan ,  AST_FLAG_END_DTMF_ONLY ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_log ( LOG_DTMF ,  " DTMF end '%c' has duration %ld but want minimum %d, emulating on %s \n " ,  f - > subclass . integer ,  f - > len ,  AST_MIN_DTMF_DURATION ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-23 17:58:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_set_flag ( chan ,  AST_FLAG_EMULATE_DTMF ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													chan - > emulate_dtmf_digit  =  f - > subclass . integer ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-24 19:03:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													chan - > emulate_dtmf_duration  =  AST_MIN_DTMF_DURATION  -  f - > len ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-22 15:57:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-23 17:58:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-06 21:43:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_log ( LOG_DTMF ,  " DTMF end passthrough '%c' on %s \n " ,  f - > subclass . integer ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-09 16:37:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													if  ( f - > len  <  AST_MIN_DTMF_DURATION )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														f - > len  =  AST_MIN_DTMF_DURATION ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-24 19:03:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													chan - > dtmf_tv  =  now ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-06 21:43:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-06 22:34:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( chan - > audiohooks )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													struct  ast_frame  * old_frame  =  f ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 19:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f  =  ast_audiohook_write_list ( chan ,  chan - > audiohooks ,  AST_AUDIOHOOK_DIRECTION_READ ,  f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-06 22:34:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													if  ( old_frame  ! =  f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														ast_frfree ( old_frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_FRAME_DTMF_BEGIN : 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											send_dtmf_event ( chan ,  " Received " ,  f - > subclass . integer ,  " Yes " ,  " No " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_DTMF ,  " DTMF begin '%c' received on %s \n " ,  f - > subclass . integer ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 23:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  (  ast_test_flag ( chan ,  AST_FLAG_DEFER_DTMF  |  AST_FLAG_END_DTMF_ONLY  |  AST_FLAG_EMULATE_DTMF )  | |  
							 
						 
					
						
							
								
									
										
										
										
											2007-04-24 19:03:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											    ( ! ast_tvzero ( chan - > dtmf_tv )  & &  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											      ast_tvdiff_ms ( ast_tvnow ( ) ,  chan - > dtmf_tv )  <  AST_MIN_DTMF_GAP )  )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_DTMF ,  " DTMF begin ignored '%c' on %s \n " ,  f - > subclass . integer ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_set_flag ( chan ,  AST_FLAG_IN_DTMF ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-24 19:03:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												chan - > dtmf_tv  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_DTMF ,  " DTMF begin passthrough '%c' on %s \n " ,  f - > subclass . integer ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 62942 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r62942 | russell | 2007-05-03 10:23:13 -0500 (Thu, 03 May 2007) | 17 lines
Fix YADB (Yet Another DTMF Bug) ((C) Russell Bryant, 2007, TM, Patent Pending).
This set of changes came from a debugging session I had with Dwayne Hubbard.
When he called into his home FXO, ran the Echo application, and pressed a
digit, the digit would be echoed back and would never end.  This is fixed,
along with a couple other little improvements.
* When chan_zap is in the middle of playing a digit to a channel, it feeds
  back null frames, not voice frames.  So, I have modified ast_read to check
  the timing on emulated DTMF when it receives null frames, in addition to
  where it was doing this on voice frames.
* Make a tweak to setting the duration on emulated DTMF digits.  If there was
  no duration specified, it set it to be the minimum, instead of the default.
* Instead of timing the emulated digits off of the number of samples in audio
  frames that pass through, just use time values.  Now there is no code in this
  section that assumes 8kHz audio.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@62943 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-05-03 15:23:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_FRAME_NULL : 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-03 15:30:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  is  reached  ,  because  we  want  to  make  sure  we  pass  at  least  one 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  voice  frame  through  before  starting  the  next  digit ,  to  ensure  a  gap 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  between  DTMF  digits .  */ 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 62942 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r62942 | russell | 2007-05-03 10:23:13 -0500 (Thu, 03 May 2007) | 17 lines
Fix YADB (Yet Another DTMF Bug) ((C) Russell Bryant, 2007, TM, Patent Pending).
This set of changes came from a debugging session I had with Dwayne Hubbard.
When he called into his home FXO, ran the Echo application, and pressed a
digit, the digit would be echoed back and would never end.  This is fixed,
along with a couple other little improvements.
* When chan_zap is in the middle of playing a digit to a channel, it feeds
  back null frames, not voice frames.  So, I have modified ast_read to check
  the timing on emulated DTMF when it receives null frames, in addition to
  where it was doing this on voice frames.
* Make a tweak to setting the duration on emulated DTMF digits.  If there was
  no duration specified, it set it to be the minimum, instead of the default.
* Instead of timing the emulated digits off of the number of samples in audio
  frames that pass through, just use time values.  Now there is no code in this
  section that assumes 8kHz audio.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@62943 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-05-03 15:23:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ast_test_flag ( chan ,  AST_FLAG_EMULATE_DTMF ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												struct  timeval  now  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-03 15:30:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( ! chan - > emulate_dtmf_duration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_clear_flag ( chan ,  AST_FLAG_EMULATE_DTMF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													chan - > emulate_dtmf_digit  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												}  else  if  ( ast_tvdiff_ms ( now ,  chan - > dtmf_tv )  > =  chan - > emulate_dtmf_duration )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 62942 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r62942 | russell | 2007-05-03 10:23:13 -0500 (Thu, 03 May 2007) | 17 lines
Fix YADB (Yet Another DTMF Bug) ((C) Russell Bryant, 2007, TM, Patent Pending).
This set of changes came from a debugging session I had with Dwayne Hubbard.
When he called into his home FXO, ran the Echo application, and pressed a
digit, the digit would be echoed back and would never end.  This is fixed,
along with a couple other little improvements.
* When chan_zap is in the middle of playing a digit to a channel, it feeds
  back null frames, not voice frames.  So, I have modified ast_read to check
  the timing on emulated DTMF when it receives null frames, in addition to
  where it was doing this on voice frames.
* Make a tweak to setting the duration on emulated DTMF digits.  If there was
  no duration specified, it set it to be the minimum, instead of the default.
* Instead of timing the emulated digits off of the number of samples in audio
  frames that pass through, just use time values.  Now there is no code in this
  section that assumes 8kHz audio.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@62943 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-05-03 15:23:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													chan - > emulate_dtmf_duration  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-09 19:24:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													f  =  & chan - > dtmff ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 62942 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r62942 | russell | 2007-05-03 10:23:13 -0500 (Thu, 03 May 2007) | 17 lines
Fix YADB (Yet Another DTMF Bug) ((C) Russell Bryant, 2007, TM, Patent Pending).
This set of changes came from a debugging session I had with Dwayne Hubbard.
When he called into his home FXO, ran the Echo application, and pressed a
digit, the digit would be echoed back and would never end.  This is fixed,
along with a couple other little improvements.
* When chan_zap is in the middle of playing a digit to a channel, it feeds
  back null frames, not voice frames.  So, I have modified ast_read to check
  the timing on emulated DTMF when it receives null frames, in addition to
  where it was doing this on voice frames.
* Make a tweak to setting the duration on emulated DTMF digits.  If there was
  no duration specified, it set it to be the minimum, instead of the default.
* Instead of timing the emulated digits off of the number of samples in audio
  frames that pass through, just use time values.  Now there is no code in this
  section that assumes 8kHz audio.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@62943 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-05-03 15:23:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f - > frametype  =  AST_FRAME_DTMF_END ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f - > subclass . integer  =  chan - > emulate_dtmf_digit ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 62942 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r62942 | russell | 2007-05-03 10:23:13 -0500 (Thu, 03 May 2007) | 17 lines
Fix YADB (Yet Another DTMF Bug) ((C) Russell Bryant, 2007, TM, Patent Pending).
This set of changes came from a debugging session I had with Dwayne Hubbard.
When he called into his home FXO, ran the Echo application, and pressed a
digit, the digit would be echoed back and would never end.  This is fixed,
along with a couple other little improvements.
* When chan_zap is in the middle of playing a digit to a channel, it feeds
  back null frames, not voice frames.  So, I have modified ast_read to check
  the timing on emulated DTMF when it receives null frames, in addition to
  where it was doing this on voice frames.
* Make a tweak to setting the duration on emulated DTMF digits.  If there was
  no duration specified, it set it to be the minimum, instead of the default.
* Instead of timing the emulated digits off of the number of samples in audio
  frames that pass through, just use time values.  Now there is no code in this
  section that assumes 8kHz audio.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@62943 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-05-03 15:23:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f - > len  =  ast_tvdiff_ms ( now ,  chan - > dtmf_tv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													chan - > dtmf_tv  =  now ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_clear_flag ( chan ,  AST_FLAG_EMULATE_DTMF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													chan - > emulate_dtmf_digit  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_log ( LOG_DTMF ,  " DTMF end emulation of '%c' queued on %s \n " ,  f - > subclass . integer ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-01 13:48:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													if  ( chan - > audiohooks )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														struct  ast_frame  * old_frame  =  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														f  =  ast_audiohook_write_list ( chan ,  chan - > audiohooks ,  AST_AUDIOHOOK_DIRECTION_READ ,  f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														if  ( old_frame  ! =  f )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															ast_frfree ( old_frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 62942 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r62942 | russell | 2007-05-03 10:23:13 -0500 (Thu, 03 May 2007) | 17 lines
Fix YADB (Yet Another DTMF Bug) ((C) Russell Bryant, 2007, TM, Patent Pending).
This set of changes came from a debugging session I had with Dwayne Hubbard.
When he called into his home FXO, ran the Echo application, and pressed a
digit, the digit would be echoed back and would never end.  This is fixed,
along with a couple other little improvements.
* When chan_zap is in the middle of playing a digit to a channel, it feeds
  back null frames, not voice frames.  So, I have modified ast_read to check
  the timing on emulated DTMF when it receives null frames, in addition to
  where it was doing this on voice frames.
* Make a tweak to setting the duration on emulated DTMF digits.  If there was
  no duration specified, it set it to be the minimum, instead of the default.
* Instead of timing the emulated digits off of the number of samples in audio
  frames that pass through, just use time values.  Now there is no code in this
  section that assumes 8kHz audio.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@62943 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-05-03 15:23:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_FRAME_VOICE : 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 62942 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r62942 | russell | 2007-05-03 10:23:13 -0500 (Thu, 03 May 2007) | 17 lines
Fix YADB (Yet Another DTMF Bug) ((C) Russell Bryant, 2007, TM, Patent Pending).
This set of changes came from a debugging session I had with Dwayne Hubbard.
When he called into his home FXO, ran the Echo application, and pressed a
digit, the digit would be echoed back and would never end.  This is fixed,
along with a couple other little improvements.
* When chan_zap is in the middle of playing a digit to a channel, it feeds
  back null frames, not voice frames.  So, I have modified ast_read to check
  the timing on emulated DTMF when it receives null frames, in addition to
  where it was doing this on voice frames.
* Make a tweak to setting the duration on emulated DTMF digits.  If there was
  no duration specified, it set it to be the minimum, instead of the default.
* Instead of timing the emulated digits off of the number of samples in audio
  frames that pass through, just use time values.  Now there is no code in this
  section that assumes 8kHz audio.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@62943 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-05-03 15:23:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  is  reached  ,  because  we  want  to  make  sure  we  pass  at  least  one 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											 *  voice  frame  through  before  starting  the  next  digit ,  to  ensure  a  gap 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  between  DTMF  digits .  */ 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ast_test_flag ( chan ,  AST_FLAG_EMULATE_DTMF )  & &  ! chan - > emulate_dtmf_duration )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_clear_flag ( chan ,  AST_FLAG_EMULATE_DTMF ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												chan - > emulate_dtmf_digit  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( dropaudio  | |  ast_test_flag ( chan ,  AST_FLAG_IN_DTMF ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-27 17:34:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( dropaudio ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_read_generator_actions ( chan ,  f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-31 17:18:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-27 17:34:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ast_test_flag ( chan ,  AST_FLAG_EMULATE_DTMF )  & &  ! ast_test_flag ( chan ,  AST_FLAG_IN_DTMF ) )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 62942 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r62942 | russell | 2007-05-03 10:23:13 -0500 (Thu, 03 May 2007) | 17 lines
Fix YADB (Yet Another DTMF Bug) ((C) Russell Bryant, 2007, TM, Patent Pending).
This set of changes came from a debugging session I had with Dwayne Hubbard.
When he called into his home FXO, ran the Echo application, and pressed a
digit, the digit would be echoed back and would never end.  This is fixed,
along with a couple other little improvements.
* When chan_zap is in the middle of playing a digit to a channel, it feeds
  back null frames, not voice frames.  So, I have modified ast_read to check
  the timing on emulated DTMF when it receives null frames, in addition to
  where it was doing this on voice frames.
* Make a tweak to setting the duration on emulated DTMF digits.  If there was
  no duration specified, it set it to be the minimum, instead of the default.
* Instead of timing the emulated digits off of the number of samples in audio
  frames that pass through, just use time values.  Now there is no code in this
  section that assumes 8kHz audio.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@62943 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-05-03 15:23:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												struct  timeval  now  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( ast_tvdiff_ms ( now ,  chan - > dtmf_tv )  > =  chan - > emulate_dtmf_duration )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													chan - > emulate_dtmf_duration  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-09 19:24:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													f  =  & chan - > dtmff ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f - > frametype  =  AST_FRAME_DTMF_END ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f - > subclass . integer  =  chan - > emulate_dtmf_digit ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-24 19:03:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f - > len  =  ast_tvdiff_ms ( now ,  chan - > dtmf_tv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													chan - > dtmf_tv  =  now ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-06 22:34:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													if  ( chan - > audiohooks )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														struct  ast_frame  * old_frame  =  f ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 19:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														f  =  ast_audiohook_write_list ( chan ,  chan - > audiohooks ,  AST_AUDIOHOOK_DIRECTION_READ ,  f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-06 22:34:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														if  ( old_frame  ! =  f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															ast_frfree ( old_frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_log ( LOG_DTMF ,  " DTMF end emulation of '%c' queued on %s \n " ,  f - > subclass . integer ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 62942 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r62942 | russell | 2007-05-03 10:23:13 -0500 (Thu, 03 May 2007) | 17 lines
Fix YADB (Yet Another DTMF Bug) ((C) Russell Bryant, 2007, TM, Patent Pending).
This set of changes came from a debugging session I had with Dwayne Hubbard.
When he called into his home FXO, ran the Echo application, and pressed a
digit, the digit would be echoed back and would never end.  This is fixed,
along with a couple other little improvements.
* When chan_zap is in the middle of playing a digit to a channel, it feeds
  back null frames, not voice frames.  So, I have modified ast_read to check
  the timing on emulated DTMF when it receives null frames, in addition to
  where it was doing this on voice frames.
* Make a tweak to setting the duration on emulated DTMF digits.  If there was
  no duration specified, it set it to be the minimum, instead of the default.
* Instead of timing the emulated digits off of the number of samples in audio
  frames that pass through, just use time values.  Now there is no code in this
  section that assumes 8kHz audio.
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@62943 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-05-03 15:23:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													/* Drop voice frames while we're still in the middle of the digit */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											}  else  if  ( ( f - > frametype  = =  AST_FRAME_VOICE )  & &  ! ( f - > subclass . codec  &  chan - > nativeformats ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-19 17:02:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												/* This frame is not one of the current native formats -- drop it on the floor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												char  to [ 200 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_NOTICE ,  " Dropping incompatible voice frame on %s of format %s since our native format has changed to %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													chan - > name ,  ast_getformatname ( f - > subclass . codec ) ,  ast_getformatname_multiple ( to ,  sizeof ( to ) ,  chan - > nativeformats ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-31 17:18:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-27 17:34:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											}  else  if  ( ( f - > frametype  = =  AST_FRAME_VOICE ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 19:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												/* Send frame to audiohooks if present */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-06 22:34:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( chan - > audiohooks )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													struct  ast_frame  * old_frame  =  f ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 19:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f  =  ast_audiohook_write_list ( chan ,  chan - > audiohooks ,  AST_AUDIOHOOK_DIRECTION_READ ,  f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-06 22:34:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													if  ( old_frame  ! =  f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														ast_frfree ( old_frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( chan - > monitor  & &  chan - > monitor - > read_stream  )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-09 07:51:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													/* XXX what does this do ? */ 
							 
						 
					
						
							
								
									
										
										
										
											2003-08-28 20:02:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifndef MONITOR_CONSTANT_DELAY 
 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													int  jump  =  chan - > outsmpl  -  chan - > insmpl  -  4  *  f - > samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( jump  > =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-16 17:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														jump  =  calc_monitor_jump ( ( chan - > outsmpl  -  chan - > insmpl ) ,  ast_format_rate ( f - > subclass . codec ) ,  ast_format_rate ( chan - > monitor - > read_stream - > fmt - > format ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-24 01:00:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														if  ( ast_seekstream ( chan - > monitor - > read_stream ,  jump ,  SEEK_FORCECUR )  = =  - 1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
															ast_log ( LOG_WARNING ,  " Failed to perform seek in monitoring read stream, synchronization between the files may be broken \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-16 17:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														chan - > insmpl  + =  ( chan - > outsmpl  -  chan - > insmpl )  +  f - > samples ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														chan - > insmpl + =  f - > samples ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-08-28 20:02:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# else 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-16 17:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													int  jump  =  calc_monitor_jump ( ( chan - > outsmpl  -  chan - > insmpl ) ,  ast_format_rate ( f - > subclass . codec ) ,  ast_format_rate ( chan - > monitor - > read_stream - > fmt - > format ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													if  ( jump  -  MONITOR_DELAY  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														if  ( ast_seekstream ( chan - > monitor - > read_stream ,  jump  -  f - > samples ,  SEEK_FORCECUR )  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															ast_log ( LOG_WARNING ,  " Failed to perform seek in monitoring read stream, synchronization between the files may be broken \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-16 17:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														chan - > insmpl  + =  chan - > outsmpl  -  chan - > insmpl ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														chan - > insmpl  + =  f - > samples ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-08-28 20:02:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													if  ( chan - > monitor - > state  = =  AST_MONITOR_RUNNING )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														if  ( ast_writestream ( chan - > monitor - > read_stream ,  f )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															ast_log ( LOG_WARNING ,  " Failed to write data to channel monitor read stream \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( chan - > readtrans  & &  ( f  =  ast_translate ( chan - > readtrans ,  f ,  1 ) )  = =  NULL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 13:58:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													f  =  & ast_null_frame ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* it is possible for the translation process on chan->readtrans to have
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												   produced  multiple  frames  from  the  single  input  frame  we  passed  it ;  if 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												   this  happens ,  queue  the  additional  frames  * before *  the  frames  we  may 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												   have  queued  earlier .  if  the  readq  was  empty ,  put  them  at  the  head  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												   the  queue ,  and  if  it  was  not ,  put  them  just  after  the  frame  that  was 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												   at  the  end  of  the  queue . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( AST_LIST_NEXT ( f ,  frame_list ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( ! readq_tail )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														ast_queue_frame_head ( chan ,  AST_LIST_NEXT ( f ,  frame_list ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														__ast_queue_frame ( chan ,  AST_LIST_NEXT ( f ,  frame_list ) ,  0 ,  readq_tail ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_frfree ( AST_LIST_NEXT ( f ,  frame_list ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													AST_LIST_NEXT ( f ,  frame_list )  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* Run generator sitting on the line if timing device not available
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												*  and  synchronous  generation  of  outgoing  frames  is  necessary        */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_read_generator_actions ( chan ,  f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-05-28 19:38:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* Just pass it on! */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Make sure we always return NULL in the future */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! chan - > _softhangup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											chan - > _softhangup  | =  AST_SOFTHANGUP_DEV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-04-24 22:16:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( cause ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											chan - > hangupcause  =  cause ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( chan - > generator ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-07 14:43:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_deactivate_generator ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-03 17:16:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* We no longer End the CDR here */ 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-05-14 23:26:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* High bit prints debugging */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 14:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > fin  &  DEBUGCHAN_FLAG ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-03-12 06:00:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_frame_dump ( chan - > name ,  f ,  " << " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 14:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									chan - > fin  =  FRAMECOUNT_INC ( chan - > fin ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 17:41:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								done : 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-22 18:52:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > music_state  & &  chan - > generator  & &  chan - > generator - > digit  & &  f  & &  f - > frametype  = =  AST_FRAME_DTMF_END ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > generator - > digit ( chan ,  f - > subclass . integer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-22 18:52:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-27 20:57:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > audiohooks  & &  ast_audiohook_write_list_empty ( chan - > audiohooks ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* The list gets recreated if audiohooks are added again later */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_audiohook_detach_list ( chan - > audiohooks ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > audiohooks  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									return  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-03-30 06:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_internal_timing_enabled ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-02 23:30:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ( ast_opt_internal_timing  & &  chan - > timingfd  >  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-03-30 06:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-20 13:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_frame  * ast_read ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  __ast_read ( chan ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_frame  * ast_read_noaudio ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  __ast_read ( chan ,  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_indicate ( struct  ast_channel  * chan ,  int  condition ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-10 12:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ast_indicate_data ( chan ,  condition ,  NULL ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  attribute_const  is_visible_indication ( enum  ast_control_frame_type  condition ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Don't include a default case here so that we get compiler warnings
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  when  a  new  type  is  added .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( condition )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_PROGRESS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_PROCEEDING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_VIDUPDATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_SRCUPDATE : 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-12 22:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_SRCCHANGE : 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_RADIO_KEY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_RADIO_UNKEY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_OPTION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_WINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_FLASH : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_OFFHOOK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_TAKEOFFHOOK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_ANSWER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_HANGUP : 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_CONNECTED_LINE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_REDIRECTING : 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 16:47:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_TRANSFER : 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 19:27:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_T38_PARAMETERS : 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Rework of T.38 negotiation and UDPTL API to address interoperability problems
Over the past couple of months, a number of issues with Asterisk
negotiating (and successfully completing) T.38 sessions with various
endpoints have been found. This patch attempts to address many of
them, primarily focused around ensuring that the endpoints'
MaxDatagram size is honored, and in addition by ensuring that T.38
session parameter negotiation is performed correctly according to the
ITU T.38 Recommendation.
The major changes here are:
1) T.38 applications in Asterisk (app_fax) only generate/receive IFP
packets, they do not ever work with UDPTL packets. As a result of
this, they cannot be allowed to generate packets that would overflow
the other endpoints' MaxDatagram size after the UDPTL stack adds any
error correction information. With this patch, the application is told
the maximum *IFP* size it can generate, based on a calculation using
the far end MaxDatagram size and the active error correction mode on
the T.38 session. The same is true for sending *our* MaxDatagram size
to the remote endpoint; it is computed from the value that the
application says it can accept (for a single IFP packet) combined with
the active error correction mode.
2) All treatment of T.38 session parameters as 'capabilities' in
chan_sip has been removed; these parameters are not at all like
audio/video stream capabilities. There are strict rules to follow for
computing an answer to a T.38 offer, and chan_sip now follows those
rules, using the desired parameters from the application (or channel)
that wants to accept the T.38 negotiation.
3) chan_sip now stores and forwards ast_control_t38_parameters
structures for tracking 'our' and 'their' T.38 session parameters;
this greatly simplifies negotiation, especially for pass-through
calls.
4) Since T.38 negotiation without specifying parameters or receiving
the final negotiated parameters is not very worthwhile, the
AST_CONTROL_T38 control frame has been removed. A note has been added
to UPGRADE.txt about this removal, since any out-of-tree applications
that use it will no longer function properly until they are upgraded
to use AST_CONTROL_T38_PARAMETERS.
Review: https://reviewboard.asterisk.org/r/310/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@208464 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-07-23 21:57:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  _XXX_AST_CONTROL_T38 : 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merge Call completion support into trunk.
From Reviewboard:
CCSS stands for Call Completion Supplementary Services. An admittedly out-of-date
overview of the architecture can be found in the file doc/CCSS_architecture.pdf
in the CCSS branch. Off the top of my head, the big differences between what is
implemented and what is in the document are as follows:
1. We did not end up modifying the Hangup application at all.
2. The document states that a single call completion monitor may be used across
   multiple calls to the same device. This proved to not be such a good idea
   when implementing protocol-specific monitors, and so we ended up using one
   monitor per-device per-call.
3. There are some configuration options which were conceived after the document
   was written. These are documented in the ccss.conf.sample that is on this
   review request.
		      
For some basic understanding of terminology used throughout this code, see the
ccss.tex document that is on this review.
This implements CCBS and CCNR in several flavors.
First up is a "generic" implementation, which can work over any channel technology
provided that the channel technology can accurately report device state. Call
completion is requested using the dialplan application CallCompletionRequest and can
be canceled using CallCompletionCancel. Device state subscriptions are used in order
to monitor the state of called parties.
Next, there is a SIP-specific implementation of call completion. This method uses the
methods outlined in draft-ietf-bliss-call-completion-06 to implement call completion
using SIP signaling. There are a few things to note here:
* The agent/monitor terminology used throughout Asterisk sometimes is the reverse of
  what is defined in the referenced draft.
* Implementation of the draft required support for SIP PUBLISH. I attempted to write
  this in a generic-enough fashion such that if someone were to want to write PUBLISH
  support for other event packages, such as dialog-state or presence, most of the effort
  would be in writing callbacks specific to the event package.
* A subportion of supporting PUBLISH reception was that we had to implement a PIDF
  parser. The PIDF support added is a bit minimal. I first wrote a validation
  routine to ensure that the PIDF document is formatted properly. The rest of the
  PIDF reading is done in-line in the call-completion-specific PUBLISH-handling
  code. In other words, while there is PIDF support here, it is not in any state
  where it could easily be applied to other event packages as is.
Finally, there are a variety of ISDN-related call completion protocols supported. These
were written by Richard Mudgett, and as such I can't really say much about their
implementation. There are notes in the CHANGES file that indicate the ISDN protocols
over which call completion is supported.
Review: https://reviewboard.asterisk.org/r/523
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-04-09 15:31:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_CC : 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_READ_ACTION : 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Generic Advice of Charge.
Asterisk Generic AOC Representation
- Generic AOC encode/decode routines.
  (Generic AOC must be encoded to be passed on the wire in the AST_CONTROL_AOC frame)
- AST_CONTROL_AOC frame type to represent generic encoded AOC data
- Manager events for AOC-S, AOC-D, and AOC-E messages
Asterisk App Support
- app_dial AOC-S pass-through support on call setup
- app_queue AOC-S pass-through support on call setup
AOC Unit Tests
- AOC Unit Tests for encode/decode routines
- AOC Unit Test for manager event representation.
SIP AOC Support
- Pass-through of generic AOC-D and AOC-E messages to snom phones via the
  snom AOC specification.
- Creation of chan_sip page3 flags for the addition of the new
  'snom_aoc_enabled' sip.conf option.
IAX AOC Support
- Natively supports AOC pass-through through the use of the new
  AST_CONTROL_AOC frame type
DAHDI AOC Support
- ETSI PRI full AOC Pass-through support
- 'aoc_enable' chan_dahdi.conf option for independently enabling
  pass-through of AOC-S, AOC-D, AOC-E.
- 'aoce_delayhangup' option for retrieving AOC-E on disconnect.
- DAHDI A() dial string option for requesting AOC services.
  example usage:
  ;requests AOC-S, AOC-D, and AOC-E on call setup
  exten=>1111,1,Dial(DAHDI/g1/1112/A(s,d,e))
Review:	https://reviewboard.asterisk.org/r/552/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@267096 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-06-02 18:10:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_AOC : 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_END_OF_Q : 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-16 19:53:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_UPDATE_RTP_PEER : 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-09 16:09:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_INCOMPLETE : 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_CONGESTION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_BUSY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_RINGING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_RING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_HOLD : 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-22 15:47:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* You can hear these */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-22 15:47:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_UNHOLD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* This is a special case.  You stop hearing this. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_indicate_data ( struct  ast_channel  * chan ,  int  _condition , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										const  void  * data ,  size_t  datalen ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* By using an enum, we'll get compiler warnings for values not handled 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  in  switch  statements .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									enum  ast_control_frame_type  condition  =  _condition ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 20:41:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_tone_zone_sound  * ts  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* this frame is used by framehooks. if it is set, we must free it at the end of this function */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_frame  * awesome_frame  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-19 06:58:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Don't bother if the channel is about to go away, anyway. */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-24 22:38:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( chan ,  AST_FLAG_ZOMBIE )  | |  ast_check_hangup ( chan ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										goto  indicate_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_framehook_list_is_empty ( chan - > framehooks ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Do framehooks now, do it, go, go now */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										struct  ast_frame  frame  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											. frametype  =  AST_FRAME_CONTROL , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											. subclass . integer  =  condition , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											. data . ptr  =  ( void  * )  data ,  /* this cast from const is only okay because we do the ast_frdup below */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											. datalen  =  datalen 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* we have now committed to freeing this frame */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										awesome_frame  =  ast_frdup ( & frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* who knows what we will get back! the anticipation is killing me. */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-09 14:09:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! ( awesome_frame  =  ast_framehook_list_write_event ( chan - > framehooks ,  awesome_frame ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											| |  awesome_frame - > frametype  ! =  AST_FRAME_CONTROL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											goto  indicate_cleanup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										condition  =  awesome_frame - > subclass . integer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										data  =  awesome_frame - > data . ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										datalen  =  awesome_frame - > datalen ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-24 22:38:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									switch  ( condition )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_CONNECTED_LINE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											struct  ast_party_connected_line  connected ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_party_connected_line_set_init ( & connected ,  & chan - > connected ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											res  =  ast_connected_line_parse_data ( data ,  datalen ,  & connected ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ! res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_channel_set_connected_line ( chan ,  & connected ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_party_connected_line_free ( & connected ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_REDIRECTING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											struct  ast_party_redirecting  redirecting ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_party_redirecting_set_init ( & redirecting ,  & chan - > redirecting ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											res  =  ast_redirecting_parse_data ( data ,  datalen ,  & redirecting ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ! res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_channel_set_redirecting ( chan ,  & redirecting ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_party_redirecting_free ( & redirecting ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-06 13:38:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-22 15:47:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( is_visible_indication ( condition ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* A new visible indication is requested. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > visible_indication  =  condition ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( condition  = =  AST_CONTROL_UNHOLD  | |  _condition  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Visible indication is cleared/stopped. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > visible_indication  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > tech - > indicate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* See if the channel driver can handle this condition. */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-10 12:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  chan - > tech - > indicate ( chan ,  condition ,  data ,  datalen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-07-06 13:38:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* The channel driver successfully handled this indication */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										goto  indicate_cleanup ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* The channel driver does not support this indication, let's fake
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  it  by  doing  our  own  tone  generation  if  applicable .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-23 04:32:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/*!\note If we compare the enumeration type, which does not have any
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  negative  constants ,  the  compiler  may  optimize  this  code  away . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Therefore ,  we  must  perform  an  integer  comparison  here .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( _condition  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* Stop any tones that are playing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_playtones_stop ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										goto  indicate_cleanup ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Handle conditions that we have tones for. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( condition )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Rework of T.38 negotiation and UDPTL API to address interoperability problems
Over the past couple of months, a number of issues with Asterisk
negotiating (and successfully completing) T.38 sessions with various
endpoints have been found. This patch attempts to address many of
them, primarily focused around ensuring that the endpoints'
MaxDatagram size is honored, and in addition by ensuring that T.38
session parameter negotiation is performed correctly according to the
ITU T.38 Recommendation.
The major changes here are:
1) T.38 applications in Asterisk (app_fax) only generate/receive IFP
packets, they do not ever work with UDPTL packets. As a result of
this, they cannot be allowed to generate packets that would overflow
the other endpoints' MaxDatagram size after the UDPTL stack adds any
error correction information. With this patch, the application is told
the maximum *IFP* size it can generate, based on a calculation using
the far end MaxDatagram size and the active error correction mode on
the T.38 session. The same is true for sending *our* MaxDatagram size
to the remote endpoint; it is computed from the value that the
application says it can accept (for a single IFP packet) combined with
the active error correction mode.
2) All treatment of T.38 session parameters as 'capabilities' in
chan_sip has been removed; these parameters are not at all like
audio/video stream capabilities. There are strict rules to follow for
computing an answer to a T.38 offer, and chan_sip now follows those
rules, using the desired parameters from the application (or channel)
that wants to accept the T.38 negotiation.
3) chan_sip now stores and forwards ast_control_t38_parameters
structures for tracking 'our' and 'their' T.38 session parameters;
this greatly simplifies negotiation, especially for pass-through
calls.
4) Since T.38 negotiation without specifying parameters or receiving
the final negotiated parameters is not very worthwhile, the
AST_CONTROL_T38 control frame has been removed. A note has been added
to UPGRADE.txt about this removal, since any out-of-tree applications
that use it will no longer function properly until they are upgraded
to use AST_CONTROL_T38_PARAMETERS.
Review: https://reviewboard.asterisk.org/r/310/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@208464 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-07-23 21:57:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  _XXX_AST_CONTROL_T38 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* deprecated T.38 control frame */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										goto  indicate_cleanup ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-07-06 13:38:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_T38_PARAMETERS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* there is no way to provide 'default' behavior for these
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  control  frames ,  so  we  need  to  return  failure ,  but  there 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  is  also  no  value  in  the  log  message  below  being  emitted 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  since  failure  to  handle  these  frames  is  not  an  ' error ' 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Improve handling of T.38 re-INVITEs that arrive before a T.38-capable
application is executing on a channel.
This patch addresses an issue found during working with end-users
using res_fax. If an incoming call is answered in the dialplan, or
jumps to the 'fax' extension due to reception of a CNG tone (with
faxdetect enabled), and then the remote endpoint sends a T.38
re-INVITE, it is possible for the channel's T.38 state to be
'T38_STATE_NEGOTIATING' when the application starts up. Unfortunately,
even if the application wants to use T.38, it can't respond to the
peer's negotiation request, because the AST_CONTROL_T38_PARAMETERS
control frame that chan_sip sent originally has been lost, and the
application needs the content of that frame to be able to formulate a
reply.
This patch adds a new 'request' type to AST_CONTROL_T38_PARAMETERS,
AST_T38_REQUEST_PARMS. If the application sends this request, chan_sip
will re-send the original control frame (with
AST_T38_REQUEST_NEGOTIATE as the request type), and the application
can respond as normal. If this occurs within the five second timeout
in chan_sip, the automatic cancellation of the peer reinvite will be
stopped, and the application will 'own' the negotiation process from
that point onwards.
This also improves the code path in chan_sip to allow sip_indicate(),
when called for AST_CONTROL_T38_PARAMETERS, to be able to return a
non-zero response, which should have been in place before since the
control frame *can* fail to be processed properly. It also modifies
ast_indicate() to return whatever result the channel driver returned
for this control frame, rather than converting all non-zero results
into '-1'. Finally, the new request type intentionally returns a
positive value, so that an application that sends
AST_T38_REQUEST_PARMS can know for certain whether the channel driver
accepted it and will be replying with a control frame of its own, or
whether it was ignored (if the sip_indicate()/ast_indicate() path had
properly supported failure responses before, this would not be
necessary).
This patch also modifies res_fax to take advantage of the new request.
In addition, this patch makes sip_t38_abort() actually lock the
private structure before doing its work... bad programmer, no donut.
This patch also enhances chan_sip's 'faxdetect' support to allow
triggering on T.38 re-INVITEs received as well as CNG tone detection.
Review: https://reviewboard.asterisk.org/r/556/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@254450 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-03-25 15:27:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										 *  so  just  return  right  now .  in  addition ,  we  want  to  return 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  whatever  value  the  channel  driver  returned ,  in  case  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  has  some  meaning . */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										goto  indicate_cleanup ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_RINGING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ts  =  ast_get_indication_tone ( chan - > zone ,  " ring " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-12 19:07:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* It is common practice for channel drivers to return -1 if trying
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  to  indicate  ringing  on  a  channel  which  is  up .  The  idea  is  to  let  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  core  generate  the  ringing  inband .  However ,  we  don ' t  want  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  warning  message  about  not  being  able  to  handle  the  specific  indication 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  to  print  nor  do  we  want  ast_indicate_data  to  return  an  " error "  for  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  condition 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( chan - > _state  = =  AST_STATE_UP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_BUSY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ts  =  ast_get_indication_tone ( chan - > zone ,  " busy " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-09 16:09:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_INCOMPLETE : 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_CONGESTION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ts  =  ast_get_indication_tone ( chan - > zone ,  " congestion " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_PROGRESS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_PROCEEDING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_VIDUPDATE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_SRCUPDATE : 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-12 22:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_SRCCHANGE : 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_RADIO_KEY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_RADIO_UNKEY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_OPTION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_WINK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_FLASH : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_OFFHOOK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_TAKEOFFHOOK : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_ANSWER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_HANGUP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_RING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_HOLD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_UNHOLD : 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 16:47:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_TRANSFER : 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_CONNECTED_LINE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_REDIRECTING : 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merge Call completion support into trunk.
From Reviewboard:
CCSS stands for Call Completion Supplementary Services. An admittedly out-of-date
overview of the architecture can be found in the file doc/CCSS_architecture.pdf
in the CCSS branch. Off the top of my head, the big differences between what is
implemented and what is in the document are as follows:
1. We did not end up modifying the Hangup application at all.
2. The document states that a single call completion monitor may be used across
   multiple calls to the same device. This proved to not be such a good idea
   when implementing protocol-specific monitors, and so we ended up using one
   monitor per-device per-call.
3. There are some configuration options which were conceived after the document
   was written. These are documented in the ccss.conf.sample that is on this
   review request.
		      
For some basic understanding of terminology used throughout this code, see the
ccss.tex document that is on this review.
This implements CCBS and CCNR in several flavors.
First up is a "generic" implementation, which can work over any channel technology
provided that the channel technology can accurately report device state. Call
completion is requested using the dialplan application CallCompletionRequest and can
be canceled using CallCompletionCancel. Device state subscriptions are used in order
to monitor the state of called parties.
Next, there is a SIP-specific implementation of call completion. This method uses the
methods outlined in draft-ietf-bliss-call-completion-06 to implement call completion
using SIP signaling. There are a few things to note here:
* The agent/monitor terminology used throughout Asterisk sometimes is the reverse of
  what is defined in the referenced draft.
* Implementation of the draft required support for SIP PUBLISH. I attempted to write
  this in a generic-enough fashion such that if someone were to want to write PUBLISH
  support for other event packages, such as dialog-state or presence, most of the effort
  would be in writing callbacks specific to the event package.
* A subportion of supporting PUBLISH reception was that we had to implement a PIDF
  parser. The PIDF support added is a bit minimal. I first wrote a validation
  routine to ensure that the PIDF document is formatted properly. The rest of the
  PIDF reading is done in-line in the call-completion-specific PUBLISH-handling
  code. In other words, while there is PIDF support here, it is not in any state
  where it could easily be applied to other event packages as is.
Finally, there are a variety of ISDN-related call completion protocols supported. These
were written by Richard Mudgett, and as such I can't really say much about their
implementation. There are notes in the CHANGES file that indicate the ISDN protocols
over which call completion is supported.
Review: https://reviewboard.asterisk.org/r/523
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-04-09 15:31:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_CC : 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_READ_ACTION : 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Generic Advice of Charge.
Asterisk Generic AOC Representation
- Generic AOC encode/decode routines.
  (Generic AOC must be encoded to be passed on the wire in the AST_CONTROL_AOC frame)
- AST_CONTROL_AOC frame type to represent generic encoded AOC data
- Manager events for AOC-S, AOC-D, and AOC-E messages
Asterisk App Support
- app_dial AOC-S pass-through support on call setup
- app_queue AOC-S pass-through support on call setup
AOC Unit Tests
- AOC Unit Tests for encode/decode routines
- AOC Unit Test for manager event representation.
SIP AOC Support
- Pass-through of generic AOC-D and AOC-E messages to snom phones via the
  snom AOC specification.
- Creation of chan_sip page3 flags for the addition of the new
  'snom_aoc_enabled' sip.conf option.
IAX AOC Support
- Natively supports AOC pass-through through the use of the new
  AST_CONTROL_AOC frame type
DAHDI AOC Support
- ETSI PRI full AOC Pass-through support
- 'aoc_enable' chan_dahdi.conf option for independently enabling
  pass-through of AOC-S, AOC-D, AOC-E.
- 'aoce_delayhangup' option for retrieving AOC-E on disconnect.
- DAHDI A() dial string option for requesting AOC services.
  example usage:
  ;requests AOC-S, AOC-D, and AOC-E on call setup
  exten=>1111,1,Dial(DAHDI/g1/1112/A(s,d,e))
Review:	https://reviewboard.asterisk.org/r/552/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@267096 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-06-02 18:10:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_AOC : 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_END_OF_Q : 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-16 19:53:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_UPDATE_RTP_PEER : 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* Nothing left to do for these. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 20:41:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ts )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* We have a tone to play, yay. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_debug ( 1 ,  " Driver for channel '%s' does not support indication %d, emulating it \n " ,  chan - > name ,  condition ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 296001 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.6.2
................
  r296001 | russell | 2010-11-24 11:03:16 -0600 (Wed, 24 Nov 2010) | 45 lines
  
  Merged revisions 296000 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r296000 | russell | 2010-11-24 10:48:39 -0600 (Wed, 24 Nov 2010) | 38 lines
    
    Handle failures building translation paths more effectively.
    
    The problem scenario occurred on a heavily loaded system that was using the
    codec_dahdi module and exceeded the hardware transcoding capacity.  The failure
    mode at that point was not good.  The report came in to us as an Asterisk
    lock-up.  The "core show locks" shows a ton of threads locked up (but no
    obvious deadlock).  Upon deeper investigation, when the system is in this
    state, the CPU was maxed out.  The CPU was being consumed by the Asterisk
    logger spewing messages on every audio frame for calls set up after transcoder
    capacity was reached.
    
    The purpose of this patch is to make Asterisk handle failures to create a
    translation path in a more graceful manner.  If we can't translate, then the
    call just needs to be dropped, as it's not going to work.  These are the
    changes:
    
    1) In set_format() of channel.c (which is called by set_read_format() and
    set_write_format()), it was ignoring if ast_translator_build_path() failed and
    returned NULL.  It now pays attention to that case and returns a result
    reflecting failure.  With this change in place, the bridging code will
    immediately detect a failure and end the bridge instead of proceeding to try to
    bridge frames that can't be translated and making channel drivers freak out by
    sending them frames in a format they weren't expecting.
    
    2) In ast_indicate_data() of channel.c, failure of ast_playtones_start() was
    ignored.  It is now reflected in the return value of the function.  This didn't
    turn out to have any affect on the bug, but seemed like a good change to leave
    in.
    
    3) In app_dial(), when only sending a call to a single endpoint, it will
    attempt to do some bridging of its own of early audio.  It uses
    make_compatible() when it's going to do this.  However, it ignored failure from
    make compatible.  So, even with the fix from #1, if there was early audio going
    through app_dial, there would still be a period of invalid frames passing
    through.  After detecting failure here, Dial() exits.
    
    ABE-2658
  ........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@296002 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-11-24 17:13:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  ast_playtones_start ( chan ,  0 ,  ts - > data ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 20:41:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ts  =  ast_tone_zone_sound_unref ( ts ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* not handled */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Unable to handle indication %d for '%s' \n " ,  condition ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-03 18:44:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								indicate_cleanup : 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-22 15:47:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( awesome_frame )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_frfree ( awesome_frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-08-13 18:29:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-12-20 15:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_recvchar ( struct  ast_channel  * chan ,  int  timeout ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 21:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  c ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  * buf  =  ast_recvtext ( chan ,  timeout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( buf  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 	/* error or timeout */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									c  =  * ( unsigned  char  * ) buf ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_free ( buf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 21:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  c ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-20 15:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-06-21 01:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								char  * ast_recvtext ( struct  ast_channel  * chan ,  int  timeout ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 21:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res ,  done  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  * buf  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-21 01:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 21:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									while  ( ! done )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										struct  ast_frame  * f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ast_check_hangup ( chan ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  ast_waitfor ( chan ,  timeout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( res  < =  0 )  /* timeout or error */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										timeout  =  res ; 	/* update timeout */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-21 01:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										f  =  ast_read ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 21:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( f  = =  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ;  /* no frame */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( f - > frametype  = =  AST_FRAME_CONTROL  & &  f - > subclass . integer  = =  AST_CONTROL_HANGUP ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 21:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											done  =  1 ; 	/* force a break */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 22:06:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										else  if  ( f - > frametype  = =  AST_FRAME_TEXT )  { 		/* what we want */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-22 16:29:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											buf  =  ast_strndup ( ( char  * )  f - > data . ptr ,  f - > datalen ) ; 	/* dup and break */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 21:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											done  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-21 01:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-23 21:28:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  buf ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-21 01:16:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-14 00:46:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_sendtext ( struct  ast_channel  * chan ,  const  char  * text ) 
							 
						 
					
						
							
								
									
										
										
										
											2000-03-26 01:59:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-03 00:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Stop if we're a zombie or need a soft hangup */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-03 00:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( chan ,  AST_FLAG_ZOMBIE )  | |  ast_check_hangup ( chan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-03 00:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2000-03-26 01:59:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									CHECK_BLOCKING ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > tech - > send_text ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  chan - > tech - > send_text ( chan ,  text ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_clear_flag ( chan ,  AST_FLAG_BLOCKING ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-03 00:24:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2000-03-26 01:59:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_senddigit_begin ( struct  ast_channel  * chan ,  char  digit ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-09 19:21:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Device does not support DTMF tones, lets fake
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  it  by  doing  our  own  generation .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-21 21:13:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									static  const  char  *  const  dtmf_tones [ ]  =  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-09 19:21:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										" 941+1336 " ,  /* 0 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 697+1209 " ,  /* 1 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 697+1336 " ,  /* 2 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 697+1477 " ,  /* 3 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 770+1209 " ,  /* 4 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 770+1336 " ,  /* 5 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 770+1477 " ,  /* 6 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 852+1209 " ,  /* 7 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 852+1336 " ,  /* 8 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 852+1477 " ,  /* 9 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 697+1633 " ,  /* A */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 770+1633 " ,  /* B */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 852+1633 " ,  /* C */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 941+1633 " ,  /* D */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 941+1209 " ,  /* * */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" 941+1477 "   /* # */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-09 19:21:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! chan - > tech - > send_digit_begin ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-05-09 19:21:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! chan - > tech - > send_digit_begin ( chan ,  digit ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( digit  > =  ' 0 '  & &  digit  < = ' 9 ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_playtones_start ( chan ,  0 ,  dtmf_tones [ digit - ' 0 ' ] ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else  if  ( digit  > =  ' A '  & &  digit  < =  ' D ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_playtones_start ( chan ,  0 ,  dtmf_tones [ digit - ' A ' + 10 ] ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else  if  ( digit  = =  ' * ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_playtones_start ( chan ,  0 ,  dtmf_tones [ 14 ] ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else  if  ( digit  = =  ' # ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_playtones_start ( chan ,  0 ,  dtmf_tones [ 15 ] ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* not handled */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_debug ( 1 ,  " Unable to generate DTMF tone '%c' for '%s' \n " ,  digit ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_senddigit_end ( struct  ast_channel  * chan ,  char  digit ,  unsigned  int  duration ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan - > tech - > send_digit_end ) 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  chan - > tech - > send_digit_end ( chan ,  digit ,  duration ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( res  & &  chan - > generator ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_playtones_stop ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-06 21:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_senddigit ( struct  ast_channel  * chan ,  char  digit ,  unsigned  int  duration ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-05-20 00:29:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-09 16:44:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > tech - > send_digit_begin )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_senddigit_begin ( chan ,  digit ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-06 21:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_safe_sleep ( chan ,  ( duration  > =  AST_DEFAULT_EMULATE_DTMF_DURATION  ?  duration  :  AST_DEFAULT_EMULATE_DTMF_DURATION ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2007-08-06 21:52:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_senddigit_end ( chan ,  digit ,  ( duration  > =  AST_DEFAULT_EMULATE_DTMF_DURATION  ?  duration  :  AST_DEFAULT_EMULATE_DTMF_DURATION ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-05-20 00:29:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-04-16 02:47:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_prod ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_frame  a  =  {  AST_FRAME_VOICE  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  nothing [ 128 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-04-16 02:47:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Send an empty audio frame to get things moving */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan - > _state  ! =  AST_STATE_UP )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_debug ( 1 ,  " Prodding channel '%s' \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										a . subclass . codec  =  chan - > rawwriteformat ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-22 16:29:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										a . data . ptr  =  nothing  +  AST_FRIENDLY_OFFSET ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-12 17:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										a . src  =  " ast_prod " ;  /* this better match check in ast_write */ 
							 
						 
					
						
							
								
									
										
										
										
											2003-04-17 02:52:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ast_write ( chan ,  & a ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Prodding channel '%s' failed \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-04-16 02:47:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-06-28 16:40:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_write_video ( struct  ast_channel  * chan ,  struct  ast_frame  * fr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! chan - > tech - > write_video ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-06-28 16:40:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									res  =  ast_write ( chan ,  fr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Fix transcode_via_sln option with SIP calls and improve PLC usage.
From reviewboard:
The problem here is a bit complex, so try to bear with me...
It was noticed by a Digium customer that generic PLC (as configured in
codecs.conf) did not appear to actually be having any sort of benefit when
packet loss was introduced on an RTP stream. I reproduced this issue myself
by streaming a file across an RTP stream and dropping approx. 5% of the
RTP packets. I saw no real difference between when PLC was enabled or disabled
when using wireshark to analyze the RTP streams.
After analyzing what was going on, it became clear that one of the problems
faced was that when running my tests, the translation paths were being set
up in such a way that PLC could not possibly work as expected. To illustrate,
if packets are lost on channel A's read stream, then we expect that PLC will
be applied to channel B's write stream. The problem is that generic PLC can
only be done when there is a translation path that moves from some codec to
SLINEAR. When I would run my tests, I found that every single time, read
and write translation paths would be set up on channel A instead of channel
B. There appeared to be no real way to predict which channel the translation
paths would be set up on.
This is where Kevin swooped in to let me know about the transcode_via_sln
option in asterisk.conf. It is supposed to work by placing a read translation
path on both channels from the channel's rawreadformat to SLINEAR. It also
will place a write translation path on both channels from SLINEAR to the
channel's rawwriteformat. Using this option allows one to predictably set up
translation paths on all channels. There are two problems with this, though.
First and foremost, the transcode_via_sln option did not appear to be working
properly when I was placing a SIP call between two endpoints which did not
share any common formats. Second, even if this option were to work, for PLC
to be applied, there had to be a write translation path that would go from
some format to SLINEAR. It would not work properly if the starting format
of translation was SLINEAR.
The one-line change presented in this review request in chan_sip.c fixed the
first issue for me. The problem was that in sip_request_call, the
jointcapability of the outbound channel was being set to the format passed to
sip_request_call. This is nativeformats of the inbound channel. Because of this,
when ast_channel_make_compatible was called by app_dial, both channels already
had compatibly read and write formats. Thus, no translation path was set up at
the time. My change is to set the jointcapability of the sip_pvt created during
sip_request_call to the intersection of the inbound channel's nativeformats and
the configured peer capability that we determined during the earlier call to
create_addr. Doing this got the translation paths set up as expected when using
transcode_via_sln.
The changes presented in channel.c fixed the second issue for me. First and
foremost, when Asterisk is started, we'll read codecs.conf to see the value of
the genericplc option. If this option is set, and ast_write is called for a
frame with no data, then we will attempt to fill in the missing samples for
the frame. The implementation uses a channel datastore for maintaining the
PLC state and for creating a buffer to store PLC samples in. Even when we
receive a frame with data, we'll call plc_rx so that the PLC state will have
knowledge of the previous voice frame, which it can use as a basis for when
it comes time to actually do a PLC fill-in.
So, reviewers, now I ask for your help. First off, there's the one line change
in chan_sip that I have put in. Is it right? By my logic it seems correct, but
I'm sure someone can tell me why it is not going to work. This is probably the
change I'm least concerned about, though. What concerns me much more is the
set of changes in channel.c. First off, am I even doing it right? When I run
tests, I can clearly see that when PLC is activated, I see a significant increase
in RTP traffic where I would expect it to be. However, in my humble opinion, the
audio sounds kind of crappy whenever the PLC fill-in is done. It sounds worse to
me than when no PLC is used at all. I need someone to review the logic I have used
to be sure that I'm not misusing anything. As far as I can see my pointer arithmetic
is correct, and my use of AST_FRIENDLY_OFFSET should be correct as well, but I'm
sure someone can point out somewhere where I've done something incorrectly.
As I was writing this review request up, I decided to give the code a test run under
valgrind, and I find that for some reason, calls to plc_rx are causing some invalid
reads. Apparently I'm reading past the end of a buffer somehow. I'll have to dig around
a bit to see why that is the case. If it's obvious to someone reviewing, speak up!
Finally, I have one other proposal that is not reflected in my code review. Since
without transcode_via_sln set, one cannot predict or control where a translation
path will be up, it seems to me that the current practice of using PLC only when
transcoding to SLINEAR is not useful. I recommend that once it has been determined
that the method used in this code review is correct and works as expected, then
the code in translate.c that invokes PLC should be removed.
Review: https://reviewboard.asterisk.org/r/622/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264452 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-19 21:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  plc_ds  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* A buffer in which to store SLIN PLC
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  samples  generated  by  the  generic  PLC 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  functionality  in  plc . c 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int16_t  * samples_buf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* The current number of samples in the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  samples_buf 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  num_samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									plc_state_t  plc_state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  plc_ds_destroy ( void  * data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  plc_ds  * plc  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_free ( plc - > samples_buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_free ( plc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  struct  ast_datastore_info  plc_ds_info  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. type  =  " plc " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. destroy  =  plc_ds_destroy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  adjust_frame_for_plc ( struct  ast_channel  * chan ,  struct  ast_frame  * frame ,  struct  ast_datastore  * datastore ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  num_new_samples  =  frame - > samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  plc_ds  * plc  =  datastore - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-10 19:34:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* As a general note, let me explain the somewhat odd calculations used when taking
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  the  frame  offset  into  account  here .  According  to  documentation  in  frame . h ,  the  frame ' s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  offset  field  indicates  the  number  of  bytes  that  the  audio  is  offset .  The  plc - > samples_buf 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  is  not  an  array  of  bytes ,  but  rather  an  array  of  16 - bit  integers  since  it  holds  SLIN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  samples .  So  I  had  two  choices  to  make  here  with  the  offset . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  1.  Make  the  offset  AST_FRIENDLY_OFFSET  bytes .  The  main  downside  for  this  is  that 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *     I  can ' t  just  add  AST_FRIENDLY_OFFSET  to  the  plc - > samples_buf  and  have  the  pointer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *     arithmetic  come  out  right .  I  would  have  to  do  some  odd  casting  or  division  for  this  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *     work  as  I  wanted . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  2.  Make  the  offset  AST_FRIENDLY_OFFSET  *  2  bytes .  This  allows  the  pointer  arithmetic 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *     to  work  out  better  with  the  plc - > samples_buf .  The  downside  here  is  that  the  buffer ' s 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *     allocation  contains  an  extra  64  bytes  of  unused  space . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  I  decided  to  go  with  option  2.  This  is  why  in  the  calloc  statement  and  the  statement  that 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  sets  the  frame ' s  offset ,  AST_FRIENDLY_OFFSET  is  multiplied  by  2. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-24 16:10:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-10 19:34:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* If this audio frame has no samples to fill in, ignore it */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-24 16:10:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! num_new_samples )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Fix transcode_via_sln option with SIP calls and improve PLC usage.
From reviewboard:
The problem here is a bit complex, so try to bear with me...
It was noticed by a Digium customer that generic PLC (as configured in
codecs.conf) did not appear to actually be having any sort of benefit when
packet loss was introduced on an RTP stream. I reproduced this issue myself
by streaming a file across an RTP stream and dropping approx. 5% of the
RTP packets. I saw no real difference between when PLC was enabled or disabled
when using wireshark to analyze the RTP streams.
After analyzing what was going on, it became clear that one of the problems
faced was that when running my tests, the translation paths were being set
up in such a way that PLC could not possibly work as expected. To illustrate,
if packets are lost on channel A's read stream, then we expect that PLC will
be applied to channel B's write stream. The problem is that generic PLC can
only be done when there is a translation path that moves from some codec to
SLINEAR. When I would run my tests, I found that every single time, read
and write translation paths would be set up on channel A instead of channel
B. There appeared to be no real way to predict which channel the translation
paths would be set up on.
This is where Kevin swooped in to let me know about the transcode_via_sln
option in asterisk.conf. It is supposed to work by placing a read translation
path on both channels from the channel's rawreadformat to SLINEAR. It also
will place a write translation path on both channels from SLINEAR to the
channel's rawwriteformat. Using this option allows one to predictably set up
translation paths on all channels. There are two problems with this, though.
First and foremost, the transcode_via_sln option did not appear to be working
properly when I was placing a SIP call between two endpoints which did not
share any common formats. Second, even if this option were to work, for PLC
to be applied, there had to be a write translation path that would go from
some format to SLINEAR. It would not work properly if the starting format
of translation was SLINEAR.
The one-line change presented in this review request in chan_sip.c fixed the
first issue for me. The problem was that in sip_request_call, the
jointcapability of the outbound channel was being set to the format passed to
sip_request_call. This is nativeformats of the inbound channel. Because of this,
when ast_channel_make_compatible was called by app_dial, both channels already
had compatibly read and write formats. Thus, no translation path was set up at
the time. My change is to set the jointcapability of the sip_pvt created during
sip_request_call to the intersection of the inbound channel's nativeformats and
the configured peer capability that we determined during the earlier call to
create_addr. Doing this got the translation paths set up as expected when using
transcode_via_sln.
The changes presented in channel.c fixed the second issue for me. First and
foremost, when Asterisk is started, we'll read codecs.conf to see the value of
the genericplc option. If this option is set, and ast_write is called for a
frame with no data, then we will attempt to fill in the missing samples for
the frame. The implementation uses a channel datastore for maintaining the
PLC state and for creating a buffer to store PLC samples in. Even when we
receive a frame with data, we'll call plc_rx so that the PLC state will have
knowledge of the previous voice frame, which it can use as a basis for when
it comes time to actually do a PLC fill-in.
So, reviewers, now I ask for your help. First off, there's the one line change
in chan_sip that I have put in. Is it right? By my logic it seems correct, but
I'm sure someone can tell me why it is not going to work. This is probably the
change I'm least concerned about, though. What concerns me much more is the
set of changes in channel.c. First off, am I even doing it right? When I run
tests, I can clearly see that when PLC is activated, I see a significant increase
in RTP traffic where I would expect it to be. However, in my humble opinion, the
audio sounds kind of crappy whenever the PLC fill-in is done. It sounds worse to
me than when no PLC is used at all. I need someone to review the logic I have used
to be sure that I'm not misusing anything. As far as I can see my pointer arithmetic
is correct, and my use of AST_FRIENDLY_OFFSET should be correct as well, but I'm
sure someone can point out somewhere where I've done something incorrectly.
As I was writing this review request up, I decided to give the code a test run under
valgrind, and I find that for some reason, calls to plc_rx are causing some invalid
reads. Apparently I'm reading past the end of a buffer somehow. I'll have to dig around
a bit to see why that is the case. If it's obvious to someone reviewing, speak up!
Finally, I have one other proposal that is not reflected in my code review. Since
without transcode_via_sln set, one cannot predict or control where a translation
path will be up, it seems to me that the current practice of using PLC only when
transcoding to SLINEAR is not useful. I recommend that once it has been determined
that the method used in this code review is correct and works as expected, then
the code in translate.c that invokes PLC should be removed.
Review: https://reviewboard.asterisk.org/r/622/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264452 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-19 21:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* First, we need to be sure that our buffer is large enough to accomodate
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  the  samples  we  need  to  fill  in .  This  will  likely  only  occur  on  the  first 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  frame  we  write . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( plc - > num_samples  <  num_new_samples )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_free ( plc - > samples_buf ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-10 19:34:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										plc - > samples_buf  =  ast_calloc ( 1 ,  ( num_new_samples  *  sizeof ( * plc - > samples_buf ) )  +  ( AST_FRIENDLY_OFFSET  *  2 ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Fix transcode_via_sln option with SIP calls and improve PLC usage.
From reviewboard:
The problem here is a bit complex, so try to bear with me...
It was noticed by a Digium customer that generic PLC (as configured in
codecs.conf) did not appear to actually be having any sort of benefit when
packet loss was introduced on an RTP stream. I reproduced this issue myself
by streaming a file across an RTP stream and dropping approx. 5% of the
RTP packets. I saw no real difference between when PLC was enabled or disabled
when using wireshark to analyze the RTP streams.
After analyzing what was going on, it became clear that one of the problems
faced was that when running my tests, the translation paths were being set
up in such a way that PLC could not possibly work as expected. To illustrate,
if packets are lost on channel A's read stream, then we expect that PLC will
be applied to channel B's write stream. The problem is that generic PLC can
only be done when there is a translation path that moves from some codec to
SLINEAR. When I would run my tests, I found that every single time, read
and write translation paths would be set up on channel A instead of channel
B. There appeared to be no real way to predict which channel the translation
paths would be set up on.
This is where Kevin swooped in to let me know about the transcode_via_sln
option in asterisk.conf. It is supposed to work by placing a read translation
path on both channels from the channel's rawreadformat to SLINEAR. It also
will place a write translation path on both channels from SLINEAR to the
channel's rawwriteformat. Using this option allows one to predictably set up
translation paths on all channels. There are two problems with this, though.
First and foremost, the transcode_via_sln option did not appear to be working
properly when I was placing a SIP call between two endpoints which did not
share any common formats. Second, even if this option were to work, for PLC
to be applied, there had to be a write translation path that would go from
some format to SLINEAR. It would not work properly if the starting format
of translation was SLINEAR.
The one-line change presented in this review request in chan_sip.c fixed the
first issue for me. The problem was that in sip_request_call, the
jointcapability of the outbound channel was being set to the format passed to
sip_request_call. This is nativeformats of the inbound channel. Because of this,
when ast_channel_make_compatible was called by app_dial, both channels already
had compatibly read and write formats. Thus, no translation path was set up at
the time. My change is to set the jointcapability of the sip_pvt created during
sip_request_call to the intersection of the inbound channel's nativeformats and
the configured peer capability that we determined during the earlier call to
create_addr. Doing this got the translation paths set up as expected when using
transcode_via_sln.
The changes presented in channel.c fixed the second issue for me. First and
foremost, when Asterisk is started, we'll read codecs.conf to see the value of
the genericplc option. If this option is set, and ast_write is called for a
frame with no data, then we will attempt to fill in the missing samples for
the frame. The implementation uses a channel datastore for maintaining the
PLC state and for creating a buffer to store PLC samples in. Even when we
receive a frame with data, we'll call plc_rx so that the PLC state will have
knowledge of the previous voice frame, which it can use as a basis for when
it comes time to actually do a PLC fill-in.
So, reviewers, now I ask for your help. First off, there's the one line change
in chan_sip that I have put in. Is it right? By my logic it seems correct, but
I'm sure someone can tell me why it is not going to work. This is probably the
change I'm least concerned about, though. What concerns me much more is the
set of changes in channel.c. First off, am I even doing it right? When I run
tests, I can clearly see that when PLC is activated, I see a significant increase
in RTP traffic where I would expect it to be. However, in my humble opinion, the
audio sounds kind of crappy whenever the PLC fill-in is done. It sounds worse to
me than when no PLC is used at all. I need someone to review the logic I have used
to be sure that I'm not misusing anything. As far as I can see my pointer arithmetic
is correct, and my use of AST_FRIENDLY_OFFSET should be correct as well, but I'm
sure someone can point out somewhere where I've done something incorrectly.
As I was writing this review request up, I decided to give the code a test run under
valgrind, and I find that for some reason, calls to plc_rx are causing some invalid
reads. Apparently I'm reading past the end of a buffer somehow. I'll have to dig around
a bit to see why that is the case. If it's obvious to someone reviewing, speak up!
Finally, I have one other proposal that is not reflected in my code review. Since
without transcode_via_sln set, one cannot predict or control where a translation
path will be up, it seems to me that the current practice of using PLC only when
transcoding to SLINEAR is not useful. I recommend that once it has been determined
that the method used in this code review is correct and works as expected, then
the code in translate.c that invokes PLC should be removed.
Review: https://reviewboard.asterisk.org/r/622/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264452 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-19 21:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! plc - > samples_buf )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_datastore_remove ( chan ,  datastore ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_datastore_free ( datastore ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										plc - > num_samples  =  num_new_samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( frame - > datalen  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-10 19:34:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										plc_fillin ( & plc - > plc_state ,  plc - > samples_buf  +  AST_FRIENDLY_OFFSET ,  frame - > samples ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame - > data . ptr  =  plc - > samples_buf  +  AST_FRIENDLY_OFFSET ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Fix transcode_via_sln option with SIP calls and improve PLC usage.
From reviewboard:
The problem here is a bit complex, so try to bear with me...
It was noticed by a Digium customer that generic PLC (as configured in
codecs.conf) did not appear to actually be having any sort of benefit when
packet loss was introduced on an RTP stream. I reproduced this issue myself
by streaming a file across an RTP stream and dropping approx. 5% of the
RTP packets. I saw no real difference between when PLC was enabled or disabled
when using wireshark to analyze the RTP streams.
After analyzing what was going on, it became clear that one of the problems
faced was that when running my tests, the translation paths were being set
up in such a way that PLC could not possibly work as expected. To illustrate,
if packets are lost on channel A's read stream, then we expect that PLC will
be applied to channel B's write stream. The problem is that generic PLC can
only be done when there is a translation path that moves from some codec to
SLINEAR. When I would run my tests, I found that every single time, read
and write translation paths would be set up on channel A instead of channel
B. There appeared to be no real way to predict which channel the translation
paths would be set up on.
This is where Kevin swooped in to let me know about the transcode_via_sln
option in asterisk.conf. It is supposed to work by placing a read translation
path on both channels from the channel's rawreadformat to SLINEAR. It also
will place a write translation path on both channels from SLINEAR to the
channel's rawwriteformat. Using this option allows one to predictably set up
translation paths on all channels. There are two problems with this, though.
First and foremost, the transcode_via_sln option did not appear to be working
properly when I was placing a SIP call between two endpoints which did not
share any common formats. Second, even if this option were to work, for PLC
to be applied, there had to be a write translation path that would go from
some format to SLINEAR. It would not work properly if the starting format
of translation was SLINEAR.
The one-line change presented in this review request in chan_sip.c fixed the
first issue for me. The problem was that in sip_request_call, the
jointcapability of the outbound channel was being set to the format passed to
sip_request_call. This is nativeformats of the inbound channel. Because of this,
when ast_channel_make_compatible was called by app_dial, both channels already
had compatibly read and write formats. Thus, no translation path was set up at
the time. My change is to set the jointcapability of the sip_pvt created during
sip_request_call to the intersection of the inbound channel's nativeformats and
the configured peer capability that we determined during the earlier call to
create_addr. Doing this got the translation paths set up as expected when using
transcode_via_sln.
The changes presented in channel.c fixed the second issue for me. First and
foremost, when Asterisk is started, we'll read codecs.conf to see the value of
the genericplc option. If this option is set, and ast_write is called for a
frame with no data, then we will attempt to fill in the missing samples for
the frame. The implementation uses a channel datastore for maintaining the
PLC state and for creating a buffer to store PLC samples in. Even when we
receive a frame with data, we'll call plc_rx so that the PLC state will have
knowledge of the previous voice frame, which it can use as a basis for when
it comes time to actually do a PLC fill-in.
So, reviewers, now I ask for your help. First off, there's the one line change
in chan_sip that I have put in. Is it right? By my logic it seems correct, but
I'm sure someone can tell me why it is not going to work. This is probably the
change I'm least concerned about, though. What concerns me much more is the
set of changes in channel.c. First off, am I even doing it right? When I run
tests, I can clearly see that when PLC is activated, I see a significant increase
in RTP traffic where I would expect it to be. However, in my humble opinion, the
audio sounds kind of crappy whenever the PLC fill-in is done. It sounds worse to
me than when no PLC is used at all. I need someone to review the logic I have used
to be sure that I'm not misusing anything. As far as I can see my pointer arithmetic
is correct, and my use of AST_FRIENDLY_OFFSET should be correct as well, but I'm
sure someone can point out somewhere where I've done something incorrectly.
As I was writing this review request up, I decided to give the code a test run under
valgrind, and I find that for some reason, calls to plc_rx are causing some invalid
reads. Apparently I'm reading past the end of a buffer somehow. I'll have to dig around
a bit to see why that is the case. If it's obvious to someone reviewing, speak up!
Finally, I have one other proposal that is not reflected in my code review. Since
without transcode_via_sln set, one cannot predict or control where a translation
path will be up, it seems to me that the current practice of using PLC only when
transcoding to SLINEAR is not useful. I recommend that once it has been determined
that the method used in this code review is correct and works as expected, then
the code in translate.c that invokes PLC should be removed.
Review: https://reviewboard.asterisk.org/r/622/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264452 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-19 21:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										frame - > datalen  =  num_new_samples  *  2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-10 19:34:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										frame - > offset  =  AST_FRIENDLY_OFFSET  *  2 ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Fix transcode_via_sln option with SIP calls and improve PLC usage.
From reviewboard:
The problem here is a bit complex, so try to bear with me...
It was noticed by a Digium customer that generic PLC (as configured in
codecs.conf) did not appear to actually be having any sort of benefit when
packet loss was introduced on an RTP stream. I reproduced this issue myself
by streaming a file across an RTP stream and dropping approx. 5% of the
RTP packets. I saw no real difference between when PLC was enabled or disabled
when using wireshark to analyze the RTP streams.
After analyzing what was going on, it became clear that one of the problems
faced was that when running my tests, the translation paths were being set
up in such a way that PLC could not possibly work as expected. To illustrate,
if packets are lost on channel A's read stream, then we expect that PLC will
be applied to channel B's write stream. The problem is that generic PLC can
only be done when there is a translation path that moves from some codec to
SLINEAR. When I would run my tests, I found that every single time, read
and write translation paths would be set up on channel A instead of channel
B. There appeared to be no real way to predict which channel the translation
paths would be set up on.
This is where Kevin swooped in to let me know about the transcode_via_sln
option in asterisk.conf. It is supposed to work by placing a read translation
path on both channels from the channel's rawreadformat to SLINEAR. It also
will place a write translation path on both channels from SLINEAR to the
channel's rawwriteformat. Using this option allows one to predictably set up
translation paths on all channels. There are two problems with this, though.
First and foremost, the transcode_via_sln option did not appear to be working
properly when I was placing a SIP call between two endpoints which did not
share any common formats. Second, even if this option were to work, for PLC
to be applied, there had to be a write translation path that would go from
some format to SLINEAR. It would not work properly if the starting format
of translation was SLINEAR.
The one-line change presented in this review request in chan_sip.c fixed the
first issue for me. The problem was that in sip_request_call, the
jointcapability of the outbound channel was being set to the format passed to
sip_request_call. This is nativeformats of the inbound channel. Because of this,
when ast_channel_make_compatible was called by app_dial, both channels already
had compatibly read and write formats. Thus, no translation path was set up at
the time. My change is to set the jointcapability of the sip_pvt created during
sip_request_call to the intersection of the inbound channel's nativeformats and
the configured peer capability that we determined during the earlier call to
create_addr. Doing this got the translation paths set up as expected when using
transcode_via_sln.
The changes presented in channel.c fixed the second issue for me. First and
foremost, when Asterisk is started, we'll read codecs.conf to see the value of
the genericplc option. If this option is set, and ast_write is called for a
frame with no data, then we will attempt to fill in the missing samples for
the frame. The implementation uses a channel datastore for maintaining the
PLC state and for creating a buffer to store PLC samples in. Even when we
receive a frame with data, we'll call plc_rx so that the PLC state will have
knowledge of the previous voice frame, which it can use as a basis for when
it comes time to actually do a PLC fill-in.
So, reviewers, now I ask for your help. First off, there's the one line change
in chan_sip that I have put in. Is it right? By my logic it seems correct, but
I'm sure someone can tell me why it is not going to work. This is probably the
change I'm least concerned about, though. What concerns me much more is the
set of changes in channel.c. First off, am I even doing it right? When I run
tests, I can clearly see that when PLC is activated, I see a significant increase
in RTP traffic where I would expect it to be. However, in my humble opinion, the
audio sounds kind of crappy whenever the PLC fill-in is done. It sounds worse to
me than when no PLC is used at all. I need someone to review the logic I have used
to be sure that I'm not misusing anything. As far as I can see my pointer arithmetic
is correct, and my use of AST_FRIENDLY_OFFSET should be correct as well, but I'm
sure someone can point out somewhere where I've done something incorrectly.
As I was writing this review request up, I decided to give the code a test run under
valgrind, and I find that for some reason, calls to plc_rx are causing some invalid
reads. Apparently I'm reading past the end of a buffer somehow. I'll have to dig around
a bit to see why that is the case. If it's obvious to someone reviewing, speak up!
Finally, I have one other proposal that is not reflected in my code review. Since
without transcode_via_sln set, one cannot predict or control where a translation
path will be up, it seems to me that the current practice of using PLC only when
transcoding to SLINEAR is not useful. I recommend that once it has been determined
that the method used in this code review is correct and works as expected, then
the code in translate.c that invokes PLC should be removed.
Review: https://reviewboard.asterisk.org/r/622/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264452 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-19 21:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										plc_rx ( & plc - > plc_state ,  frame - > data . ptr ,  frame - > samples ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  apply_plc ( struct  ast_channel  * chan ,  struct  ast_frame  * frame ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * datastore ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  plc_ds  * plc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									datastore  =  ast_channel_datastore_find ( chan ,  & plc_ds_info ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( datastore )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										plc  =  datastore - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										adjust_frame_for_plc ( chan ,  frame ,  datastore ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									datastore  =  ast_datastore_alloc ( & plc_ds_info ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! datastore )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									plc  =  ast_calloc ( 1 ,  sizeof ( * plc ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! plc )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_datastore_free ( datastore ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									datastore - > data  =  plc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_datastore_add ( chan ,  datastore ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									adjust_frame_for_plc ( chan ,  frame ,  datastore ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								int  ast_write ( struct  ast_channel  * chan ,  struct  ast_frame  * fr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_frame  * f  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-18 17:05:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  count  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 13:58:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-12-18 17:05:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/*Deadlock avoidance*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									while ( ast_channel_trylock ( chan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*cannot goto done since the channel is not locked*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if ( count + +  >  10 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_debug ( 1 ,  " Deadlock avoided for write to channel '%s' \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										usleep ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Stop if we're a zombie or need a soft hangup */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 14:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( chan ,  AST_FLAG_ZOMBIE )  | |  ast_check_hangup ( chan ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										goto  done ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Handle any pending masquerades */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > masq )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ast_do_masquerade ( chan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Failed to perform masquerade \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  res ;  /* no need to goto done: chan is already unlocked for masq */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2003-07-29 16:09:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > masqr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 14:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  0 ; 	/* XXX explain, why 0 ? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										goto  done ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-07-29 16:09:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:09:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Perform the framehook write event here. After the frame enters the framehook list
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  there  is  no  telling  what  will  happen ,  how  awesome  is  that ! ! !  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ( fr  =  ast_framehook_list_write_event ( chan - > framehooks ,  fr ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										goto  done ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-15 13:51:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > generatordata  & &  ( ! fr - > src  | |  strcasecmp ( fr - > src ,  " ast_prod " ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-12 17:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ast_test_flag ( chan ,  AST_FLAG_WRITE_INT ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_deactivate_generator ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-02 23:00:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( fr - > frametype  = =  AST_FRAME_DTMF_END )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* There is a generator running while we're in the middle of a digit.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 *  It ' s  probably  inband  DTMF ,  so  go  ahead  and  pass  it  so  it  can 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 *  stop  the  generator  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_clear_flag ( chan ,  AST_FLAG_BLOCKING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												res  =  ast_senddigit_end ( chan ,  fr - > subclass . integer ,  fr - > len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-02 23:00:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												CHECK_BLOCKING ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											}  else  if  ( fr - > frametype  = =  AST_FRAME_CONTROL  & &  fr - > subclass . integer  = =  AST_CONTROL_UNHOLD )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-14 17:25:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												/* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												res  =  ( chan - > tech - > indicate  = =  NULL )  ?  0  : 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													chan - > tech - > indicate ( chan ,  fr - > subclass . integer ,  fr - > data . ptr ,  fr - > datalen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-05-02 23:00:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 14:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											res  =  0 ; 	/* XXX explain, why 0 ? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											goto  done ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-07-29 16:09:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-14 23:26:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* High bit prints debugging */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 14:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > fout  &  DEBUGCHAN_FLAG ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-03-12 06:00:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_frame_dump ( chan - > name ,  fr ,  " >> " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									CHECK_BLOCKING ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-23 00:11:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									switch  ( fr - > frametype )  { 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_CONTROL : 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-23 05:06:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  ( chan - > tech - > indicate  = =  NULL )  ?  0  : 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											chan - > tech - > indicate ( chan ,  fr - > subclass . integer ,  fr - > data . ptr ,  fr - > datalen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_FRAME_DTMF_BEGIN : 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-06 22:34:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( chan - > audiohooks )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											struct  ast_frame  * old_frame  =  fr ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 19:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											fr  =  ast_audiohook_write_list ( chan ,  chan - > audiohooks ,  AST_AUDIOHOOK_DIRECTION_WRITE ,  fr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-06 22:34:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( old_frame  ! =  fr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												f  =  fr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										send_dtmf_event ( chan ,  " Sent " ,  fr - > subclass . integer ,  " Yes " ,  " No " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_clear_flag ( chan ,  AST_FLAG_BLOCKING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  ast_senddigit_begin ( chan ,  fr - > subclass . integer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										CHECK_BLOCKING ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:15:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_FRAME_DTMF_END : 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-06 22:34:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( chan - > audiohooks )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											struct  ast_frame  * new_frame  =  fr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											new_frame  =  ast_audiohook_write_list ( chan ,  chan - > audiohooks ,  AST_AUDIOHOOK_DIRECTION_WRITE ,  fr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( new_frame  ! =  fr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_frfree ( new_frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-06 22:34:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										send_dtmf_event ( chan ,  " Sent " ,  fr - > subclass . integer ,  " No " ,  " Yes " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_clear_flag ( chan ,  AST_FLAG_BLOCKING ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 15:07:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  ast_senddigit_end ( chan ,  fr - > subclass . integer ,  fr - > len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 15:07:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-09-24 19:43:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										CHECK_BLOCKING ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-20 15:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_FRAME_TEXT : 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( fr - > subclass . integer  = =  AST_FORMAT_T140 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-16 13:35:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											res  =  ( chan - > tech - > write_text  = =  NULL )  ?  0  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												chan - > tech - > write_text ( chan ,  fr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											res  =  ( chan - > tech - > send_text  = =  NULL )  ?  0  : 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-22 16:29:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												chan - > tech - > send_text ( chan ,  ( char  * )  fr - > data . ptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-02-16 13:35:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-02-28 06:06:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_HTML : 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 13:58:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  ( chan - > tech - > send_html  = =  NULL )  ?  0  : 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											chan - > tech - > send_html ( chan ,  fr - > subclass . integer ,  ( char  * )  fr - > data . ptr ,  fr - > datalen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-20 15:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-06-28 16:40:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_FRAME_VIDEO : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* XXX Handle translation of video codecs one day XXX */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 13:58:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  ( chan - > tech - > write_video  = =  NULL )  ?  0  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											chan - > tech - > write_video ( chan ,  fr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-06-28 16:40:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-13 18:35:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_FRAME_MODEM : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  ( chan - > tech - > write  = =  NULL )  ?  0  : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											chan - > tech - > write ( chan ,  fr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-29 05:07:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  AST_FRAME_VOICE : 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 13:58:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( chan - > tech - > write  = =  NULL ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-19 06:58:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 	/*! \todo XXX should return 0 maybe ? */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 13:58:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Fix transcode_via_sln option with SIP calls and improve PLC usage.
From reviewboard:
The problem here is a bit complex, so try to bear with me...
It was noticed by a Digium customer that generic PLC (as configured in
codecs.conf) did not appear to actually be having any sort of benefit when
packet loss was introduced on an RTP stream. I reproduced this issue myself
by streaming a file across an RTP stream and dropping approx. 5% of the
RTP packets. I saw no real difference between when PLC was enabled or disabled
when using wireshark to analyze the RTP streams.
After analyzing what was going on, it became clear that one of the problems
faced was that when running my tests, the translation paths were being set
up in such a way that PLC could not possibly work as expected. To illustrate,
if packets are lost on channel A's read stream, then we expect that PLC will
be applied to channel B's write stream. The problem is that generic PLC can
only be done when there is a translation path that moves from some codec to
SLINEAR. When I would run my tests, I found that every single time, read
and write translation paths would be set up on channel A instead of channel
B. There appeared to be no real way to predict which channel the translation
paths would be set up on.
This is where Kevin swooped in to let me know about the transcode_via_sln
option in asterisk.conf. It is supposed to work by placing a read translation
path on both channels from the channel's rawreadformat to SLINEAR. It also
will place a write translation path on both channels from SLINEAR to the
channel's rawwriteformat. Using this option allows one to predictably set up
translation paths on all channels. There are two problems with this, though.
First and foremost, the transcode_via_sln option did not appear to be working
properly when I was placing a SIP call between two endpoints which did not
share any common formats. Second, even if this option were to work, for PLC
to be applied, there had to be a write translation path that would go from
some format to SLINEAR. It would not work properly if the starting format
of translation was SLINEAR.
The one-line change presented in this review request in chan_sip.c fixed the
first issue for me. The problem was that in sip_request_call, the
jointcapability of the outbound channel was being set to the format passed to
sip_request_call. This is nativeformats of the inbound channel. Because of this,
when ast_channel_make_compatible was called by app_dial, both channels already
had compatibly read and write formats. Thus, no translation path was set up at
the time. My change is to set the jointcapability of the sip_pvt created during
sip_request_call to the intersection of the inbound channel's nativeformats and
the configured peer capability that we determined during the earlier call to
create_addr. Doing this got the translation paths set up as expected when using
transcode_via_sln.
The changes presented in channel.c fixed the second issue for me. First and
foremost, when Asterisk is started, we'll read codecs.conf to see the value of
the genericplc option. If this option is set, and ast_write is called for a
frame with no data, then we will attempt to fill in the missing samples for
the frame. The implementation uses a channel datastore for maintaining the
PLC state and for creating a buffer to store PLC samples in. Even when we
receive a frame with data, we'll call plc_rx so that the PLC state will have
knowledge of the previous voice frame, which it can use as a basis for when
it comes time to actually do a PLC fill-in.
So, reviewers, now I ask for your help. First off, there's the one line change
in chan_sip that I have put in. Is it right? By my logic it seems correct, but
I'm sure someone can tell me why it is not going to work. This is probably the
change I'm least concerned about, though. What concerns me much more is the
set of changes in channel.c. First off, am I even doing it right? When I run
tests, I can clearly see that when PLC is activated, I see a significant increase
in RTP traffic where I would expect it to be. However, in my humble opinion, the
audio sounds kind of crappy whenever the PLC fill-in is done. It sounds worse to
me than when no PLC is used at all. I need someone to review the logic I have used
to be sure that I'm not misusing anything. As far as I can see my pointer arithmetic
is correct, and my use of AST_FRIENDLY_OFFSET should be correct as well, but I'm
sure someone can point out somewhere where I've done something incorrectly.
As I was writing this review request up, I decided to give the code a test run under
valgrind, and I find that for some reason, calls to plc_rx are causing some invalid
reads. Apparently I'm reading past the end of a buffer somehow. I'll have to dig around
a bit to see why that is the case. If it's obvious to someone reviewing, speak up!
Finally, I have one other proposal that is not reflected in my code review. Since
without transcode_via_sln set, one cannot predict or control where a translation
path will be up, it seems to me that the current practice of using PLC only when
transcoding to SLINEAR is not useful. I recommend that once it has been determined
that the method used in this code review is correct and works as expected, then
the code in translate.c that invokes PLC should be removed.
Review: https://reviewboard.asterisk.org/r/622/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264452 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-19 21:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ast_opt_generic_plc  & &  fr - > subclass . codec  = =  AST_FORMAT_SLINEAR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											apply_plc ( chan ,  fr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 19:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-22 06:18:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( fr - > subclass . codec  = =  chan - > rawwriteformat )  { 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 19:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											f  =  fr ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-22 06:18:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* XXX Something is not right we are not compatible with this frame bad things can happen
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  problems  range  from  no / one - way  audio  to  unexplained  line  hangups  as  a  last  resort  try  adjust  the  format 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  ideally  we  do  not  want  to  do  this  and  this  indicates  a  deeper  problem  for  now  we  log  these  events  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  eliminate  user  impact  and  help  identify  the  problem  areas 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  JIRA  issues  related  to  this  : - 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  ASTERISK - 14384 ,  ASTERISK - 17502 ,  ASTERISK - 17541 ,  ASTERISK - 18063 ,  ASTERISK - 18325 ,  ASTERISK - 18422 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ( ! ( fr - > subclass . codec  &  chan - > nativeformats ) )  & &  ( chan - > writeformat  ! =  fr - > subclass . codec ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												char  nf [ 512 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Codec mismatch on channel %s setting write format to %s from %s native formats %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													chan - > name ,  ast_getformatname ( fr - > subclass . codec ) ,  ast_getformatname ( chan - > writeformat ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_getformatname_multiple ( nf ,  sizeof ( nf ) ,  chan - > nativeformats  &  AST_FORMAT_AUDIO_MASK ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_set_write_format ( chan ,  fr - > subclass . codec ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 19:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											f  =  ( chan - > writetrans )  ?  ast_translate ( chan - > writetrans ,  fr ,  0 )  :  fr ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-09-22 06:18:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-26 20:11:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 19:30:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! f )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 14:14:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-26 20:11:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-24 03:04:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( chan - > audiohooks )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-26 16:38:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											struct  ast_frame  * prev  =  NULL ,  * new_frame ,  * cur ,  * dup ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-06 22:35:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											int  freeoldlist  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( f  ! =  fr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												freeoldlist  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-26 16:38:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* Since ast_audiohook_write may return a new frame, and the cur frame is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  an  item  in  a  list  of  frames ,  create  a  new  list  adding  each  cur  frame  back  to  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  regardless  if  the  cur  frame  changes  or  not .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											for  ( cur  =  f ;  cur ;  cur  =  AST_LIST_NEXT ( cur ,  frame_list ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												new_frame  =  ast_audiohook_write_list ( chan ,  chan - > audiohooks ,  AST_AUDIOHOOK_DIRECTION_WRITE ,  cur ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-26 16:38:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* if this frame is different than cur, preserve the end of the list,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 *  free  the  old  frames ,  and  set  cur  to  be  the  new  frame  */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( new_frame  ! =  cur )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-06 22:35:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-26 16:38:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													/* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 *  isn ' t  part  of  local  storage ,  meaning  if  ast_audiohook_write  is  called  multiple 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													 *  times  it  may  override  the  previous  frame  we  got  from  it  unless  we  dup  it  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( ( dup  =  ast_frisolate ( new_frame ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														AST_LIST_NEXT ( dup ,  frame_list )  =  AST_LIST_NEXT ( cur ,  frame_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-06 22:35:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														if  ( freeoldlist )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															AST_LIST_NEXT ( cur ,  frame_list )  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															ast_frfree ( cur ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-29 19:13:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														if  ( new_frame  ! =  dup )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
															ast_frfree ( new_frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-26 16:38:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														cur  =  dup ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* now, regardless if cur is new or not, add it to the new list,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 *  if  the  new  list  has  not  started ,  cur  will  become  the  first  item .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( prev )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													AST_LIST_NEXT ( prev ,  frame_list )  =  cur ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													f  =  cur ;  /* set f to be the beginning of our new list */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-26 16:38:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												prev  =  cur ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										
							 
						 
					
						
							
								
									
										
										
										
											2006-09-26 20:11:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* If Monitor is running on this channel, then we have to write frames out there too */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* the translator on chan->writetrans may have returned multiple frames
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										   from  the  single  frame  we  passed  in ;  if  so ,  feed  each  one  of  them  to  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										   monitor  */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-26 20:11:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( chan - > monitor  & &  chan - > monitor - > write_stream )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											struct  ast_frame  * cur ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											for  ( cur  =  f ;  cur ;  cur  =  AST_LIST_NEXT ( cur ,  frame_list ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-26 20:11:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* XXX must explain this code */ 
							 
						 
					
						
							
								
									
										
										
										
											2003-08-28 20:02:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifndef MONITOR_CONSTANT_DELAY 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												int  jump  =  chan - > insmpl  -  chan - > outsmpl  -  4  *  cur - > samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( jump  > =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-16 17:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													jump  =  calc_monitor_jump ( ( chan - > insmpl  -  chan - > outsmpl ) ,  ast_format_rate ( f - > subclass . codec ) ,  ast_format_rate ( chan - > monitor - > read_stream - > fmt - > format ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													if  ( ast_seekstream ( chan - > monitor - > write_stream ,  jump ,  SEEK_FORCECUR )  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														ast_log ( LOG_WARNING ,  " Failed to perform seek in monitoring write stream, synchronization between the files may be broken \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-16 17:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													chan - > outsmpl  + =  ( chan - > insmpl  -  chan - > outsmpl )  +  cur - > samples ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													chan - > outsmpl  + =  cur - > samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2003-08-28 20:02:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# else 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-16 17:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												int  jump  =  calc_monitor_jump ( ( chan - > insmpl  -  chan - > outsmpl ) ,  ast_format_rate ( f - > subclass . codec ) ,  ast_format_rate ( chan - > monitor - > read_stream - > fmt - > format ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( jump  -  MONITOR_DELAY  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( ast_seekstream ( chan - > monitor - > write_stream ,  jump  -  cur - > samples ,  SEEK_FORCECUR )  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														ast_log ( LOG_WARNING ,  " Failed to perform seek in monitoring write stream, synchronization between the files may be broken \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-16 17:07:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													chan - > outsmpl  + =  chan - > insmpl  -  chan - > outsmpl ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													chan - > outsmpl  + =  cur - > samples ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2003-08-28 20:02:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( chan - > monitor - > state  = =  AST_MONITOR_RUNNING )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( ast_writestream ( chan - > monitor - > write_stream ,  cur )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														ast_log ( LOG_WARNING ,  " Failed to write data to channel monitor write stream \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 13:58:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-09-26 20:11:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-09 22:21:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* the translator on chan->writetrans may have returned multiple frames
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										   from  the  single  frame  we  passed  in ;  if  so ,  feed  each  one  of  them  to  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										   channel ,  freeing  each  one  after  it  has  been  written  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ( f  ! =  fr )  & &  AST_LIST_NEXT ( f ,  frame_list ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											struct  ast_frame  * cur ,  * next ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											unsigned  int  skip  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											for  ( cur  =  f ,  next  =  AST_LIST_NEXT ( cur ,  frame_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											     cur ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											     cur  =  next ,  next  =  cur  ?  AST_LIST_NEXT ( cur ,  frame_list )  :  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( ! skip )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( ( res  =  chan - > tech - > write ( chan ,  cur ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														chan - > _softhangup  | =  AST_SOFTHANGUP_DEV ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														skip  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													}  else  if  ( next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														/* don't do this for the last frame in the list,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														   as  the  code  outside  the  loop  will  do  it  once 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														chan - > fout  =  FRAMECOUNT_INC ( chan - > fout ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_frfree ( cur ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* reset f so the code below doesn't attempt to free it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											f  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											res  =  chan - > tech - > write ( chan ,  f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_NULL : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_FRAME_IAX : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Ignore these */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 18:47:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
									
										
										
										
											2006-10-24 03:09:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* At this point, fr is the incoming frame and f is NULL.  Channels do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  not  expect  to  get  NULL  as  a  frame  pointer  and  will  segfault .   Hence , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  we  output  the  original  frame  passed  in .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  chan - > tech - > write ( chan ,  fr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-22 21:19:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 13:58:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( f  & &  f  ! =  fr ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-12 13:59:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_clear_flag ( chan ,  AST_FLAG_BLOCKING ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Consider a write failure to force a soft hangup */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > _softhangup  | =  AST_SOFTHANGUP_DEV ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-16 18:54:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 14:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > fout  =  FRAMECOUNT_INC ( chan - > fout ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-03-12 06:00:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 14:49:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								done : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-27 20:57:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > audiohooks  & &  ast_audiohook_write_list_empty ( chan - > audiohooks ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* The list gets recreated if audiohooks are added again later */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_audiohook_detach_list ( chan - > audiohooks ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > audiohooks  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 15:07:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  set_format ( struct  ast_channel  * chan ,  format_t  fmt ,  format_t  * rawformat ,  format_t  * format , 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-04 03:28:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										      struct  ast_trans_pvt  * * trans ,  const  int  direction ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									format_t  native ,  native_fmt  =  ast_best_codec ( fmt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-19 17:02:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  from [ 200 ] ,  to [ 200 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2008-02-19 22:35:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Make sure we only consider audio */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									fmt  & =  AST_FORMAT_AUDIO_MASK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2008-02-19 22:23:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									native  =  chan - > nativeformats ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 17:12:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! fmt  | |  ! native ) 	/* No audio requested */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 	/* Let's try a call without any sounds (video, text) */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-09 16:19:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* See if the underlying channel driver is capable of performing transcoding for us */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_channel_setoption ( chan ,  direction  ?  AST_OPTION_FORMAT_WRITE  :  AST_OPTION_FORMAT_READ ,  & native_fmt ,  sizeof ( int * ) ,  0 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_debug ( 1 ,  " Channel driver natively set channel %s to %s format %s \n " ,  chan - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											  direction  ?  " write "  :  " read " ,  ast_getformatname ( native_fmt ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-09 16:19:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > nativeformats  =  * rawformat  =  * format  =  native_fmt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( * trans )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_translator_free_path ( * trans ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* trans  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-04 03:28:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Find a translation path from the native format to one of the desired formats */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! direction ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* reading */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  ast_translator_best_choice ( & fmt ,  & native ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* writing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  ast_translator_best_choice ( & native ,  & fmt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Unable to find a codec translation path from %s to %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-19 17:02:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_getformatname_multiple ( from ,  sizeof ( from ) ,  native ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_getformatname_multiple ( to ,  sizeof ( to ) ,  fmt ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-04-04 03:28:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Now we have a good choice for both. */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 15:07:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-27 15:42:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-09 20:25:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ( * rawformat  = =  native )  & &  ( * format  = =  fmt )  & &  ( ( * rawformat  = =  * format )  | |  ( * trans ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-27 15:42:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* the channel is already in these formats, so nothing to do */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-04 03:28:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									* rawformat  =  native ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* User perspective is fmt */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-04 03:28:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									* format  =  fmt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Free any read translation we have right now */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 23:29:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( * trans )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-04 03:28:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_translator_free_path ( * trans ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 23:29:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										* trans  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-04 03:28:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Build a translation path from the raw format to the desired format */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-24 20:23:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( * format  = =  * rawformat )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  If  we  were  able  to  swap  the  native  format  to  the  format  that 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  has  been  requested ,  then  there  is  no  need  to  try  to  build 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  a  translation  path . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! direction )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* reading */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* trans  =  ast_translator_build_path ( * format ,  * rawformat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* writing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* trans  =  ast_translator_build_path ( * rawformat ,  * format ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  * trans  ?  0  :  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 15:07:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_debug ( 1 ,  " Set channel %s to %s format %s \n " ,  chan - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										direction  ?  " write "  :  " read " ,  ast_getformatname ( fmt ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 296001 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.6.2
................
  r296001 | russell | 2010-11-24 11:03:16 -0600 (Wed, 24 Nov 2010) | 45 lines
  
  Merged revisions 296000 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r296000 | russell | 2010-11-24 10:48:39 -0600 (Wed, 24 Nov 2010) | 38 lines
    
    Handle failures building translation paths more effectively.
    
    The problem scenario occurred on a heavily loaded system that was using the
    codec_dahdi module and exceeded the hardware transcoding capacity.  The failure
    mode at that point was not good.  The report came in to us as an Asterisk
    lock-up.  The "core show locks" shows a ton of threads locked up (but no
    obvious deadlock).  Upon deeper investigation, when the system is in this
    state, the CPU was maxed out.  The CPU was being consumed by the Asterisk
    logger spewing messages on every audio frame for calls set up after transcoder
    capacity was reached.
    
    The purpose of this patch is to make Asterisk handle failures to create a
    translation path in a more graceful manner.  If we can't translate, then the
    call just needs to be dropped, as it's not going to work.  These are the
    changes:
    
    1) In set_format() of channel.c (which is called by set_read_format() and
    set_write_format()), it was ignoring if ast_translator_build_path() failed and
    returned NULL.  It now pays attention to that case and returns a result
    reflecting failure.  With this change in place, the bridging code will
    immediately detect a failure and end the bridge instead of proceeding to try to
    bridge frames that can't be translated and making channel drivers freak out by
    sending them frames in a format they weren't expecting.
    
    2) In ast_indicate_data() of channel.c, failure of ast_playtones_start() was
    ignored.  It is now reflected in the return value of the function.  This didn't
    turn out to have any affect on the bug, but seemed like a good change to leave
    in.
    
    3) In app_dial(), when only sending a call to a single endpoint, it will
    attempt to do some bridging of its own of early audio.  It uses
    make_compatible() when it's going to do this.  However, it ignored failure from
    make compatible.  So, even with the fix from #1, if there was early audio going
    through app_dial, there would still be a period of invalid frames passing
    through.  After detecting failure here, Dial() exits.
    
    ABE-2658
  ........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@296002 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-11-24 17:13:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_set_read_format ( struct  ast_channel  * chan ,  format_t  fmt ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-04 03:28:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  set_format ( chan ,  fmt ,  & chan - > rawreadformat ,  & chan - > readformat , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											  & chan - > readtrans ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_set_write_format ( struct  ast_channel  * chan ,  format_t  fmt ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-04 03:28:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  set_format ( chan ,  fmt ,  & chan - > rawwriteformat ,  & chan - > writeformat , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											  & chan - > writetrans ,  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-13 14:23:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								const  char  * ast_channel_reason2str ( int  reason ) 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-10 21:03:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									switch  ( reason )  /* the following appear to be the only ones actually returned by request_and_dial */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  0 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_HANGUP : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Hangup " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_RING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Local Ring " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_RINGING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Remote end Ringing " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_ANSWER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Remote end has Answered " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_BUSY : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Remote end is Busy " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  AST_CONTROL_CONGESTION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Congestion (circuits busy) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " Unknown Reason!! " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  handle_cause ( int  cause ,  int  * outstate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( outstate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* compute error and return */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( cause  = =  AST_CAUSE_BUSY ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* outstate  =  AST_CONTROL_BUSY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										else  if  ( cause  = =  AST_CAUSE_CONGESTION ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* outstate  =  AST_CONTROL_CONGESTION ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* outstate  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Helper  function  to  inherit  info  from  parent  channel . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  new_chan  Channel  inheriting  information . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  parent  Channel  new_chan  inherits  information . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  orig  Channel  being  replaced  by  the  call  forward  channel . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ return  Nothing 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  call_forward_inherit ( struct  ast_channel  * new_chan ,  struct  ast_channel  * parent ,  struct  ast_channel  * orig ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_test_flag ( parent ,  AST_FLAG_ZOMBIE )  & &  ! ast_check_hangup ( parent ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										struct  ast_party_redirecting  redirecting ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  The  parent  is  not  a  ZOMBIE  or  hungup  so  update  it  with  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  original  channel ' s  redirecting  information . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_party_redirecting_init ( & redirecting ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_lock ( orig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_party_redirecting_copy ( & redirecting ,  & orig - > redirecting ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( orig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ast_channel_redirecting_macro ( orig ,  parent ,  & redirecting ,  1 ,  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_update_redirecting ( parent ,  & redirecting ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_party_redirecting_free ( & redirecting ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Safely inherit variables and datastores from the parent channel. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock_both ( parent ,  new_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_inherit_variables ( parent ,  new_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_datastore_inherit ( parent ,  new_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( new_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( parent ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_call_forward ( struct  ast_channel  * caller ,  struct  ast_channel  * orig ,  int  * timeout ,  format_t  format ,  struct  outgoing_helper  * oh ,  int  * outstate ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  tmpchan [ 256 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * new_chan  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  * data ,  * type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  cause  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 21:12:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* gather data and request the new forward channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_copy_string ( tmpchan ,  orig - > call_forward ,  sizeof ( tmpchan ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( data  =  strchr ( tmpchan ,  ' / ' ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* data + +  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										type  =  tmpchan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										const  char  * forward_context ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_lock ( orig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										forward_context  =  pbx_builtin_getvar_helper ( orig ,  " FORWARD_CONTEXT " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										snprintf ( tmpchan ,  sizeof ( tmpchan ) ,  " %s@%s " ,  orig - > call_forward ,  S_OR ( forward_context ,  orig - > context ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( orig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										data  =  tmpchan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										type  =  " Local " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ( new_chan  =  ast_request ( type ,  format ,  orig ,  data ,  & cause ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_NOTICE ,  " Unable to create channel for call forward to '%s/%s' (cause = %d) \n " ,  type ,  data ,  cause ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										handle_cause ( cause ,  outstate ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_hangup ( orig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Copy/inherit important information into new channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( oh )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( oh - > vars )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_set_variables ( new_chan ,  oh - > vars ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( oh - > parent_channel )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											call_forward_inherit ( new_chan ,  oh - > parent_channel ,  orig ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( oh - > account )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_lock ( new_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_cdr_setaccount ( new_chan ,  oh - > account ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_unlock ( new_chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( caller )  {  /* no outgoing helper so use caller if avaliable */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										call_forward_inherit ( new_chan ,  caller ,  orig ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock_both ( orig ,  new_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_copy_flags ( new_chan - > cdr ,  orig - > cdr ,  AST_CDR_FLAG_ORIGINATED ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_string_field_set ( new_chan ,  accountcode ,  orig - > accountcode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_connected_line_copy ( & new_chan - > connected ,  & orig - > connected ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_redirecting_copy ( & new_chan - > redirecting ,  & orig - > redirecting ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( new_chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( orig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* call new channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									res  =  ast_call ( new_chan ,  data ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 21:12:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( timeout )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* timeout  =  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( res )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_NOTICE ,  " Unable to call forward to channel %s/%s \n " ,  type ,  ( char  * ) data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_hangup ( orig ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_hangup ( new_chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_hangup ( orig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  new_chan ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * __ast_request_and_dial ( const  char  * type ,  format_t  format ,  const  struct  ast_channel  * requestor ,  void  * data ,  int  timeout ,  int  * outstate ,  const  char  * cid_num ,  const  char  * cid_name ,  struct  outgoing_helper  * oh ) 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  dummy_outstate ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-26 22:25:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  cause  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * chan ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-09-12 16:51:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-11 19:12:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  last_subclass  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_party_connected_line  connected ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-18 05:00:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( outstate ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* outstate  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										outstate  =  & dummy_outstate ; 	/* make outstate always a valid pointer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									chan  =  ast_request ( type ,  format ,  requestor ,  data ,  & cause ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_NOTICE ,  " Unable to request channel %s/%s \n " ,  type ,  ( char  * ) data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										handle_cause ( cause ,  outstate ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( oh )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( oh - > vars )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_set_variables ( chan ,  oh - > vars ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! ast_strlen_zero ( oh - > cid_num )  & &  ! ast_strlen_zero ( oh - > cid_name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  Use  the  oh  values  instead  of  the  function  parameters  for  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  outgoing  CallerID . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											cid_num  =  oh - > cid_num ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											cid_name  =  oh - > cid_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-03 14:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( oh - > parent_channel )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* Safely inherit variables and datastores from the parent channel. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_lock_both ( oh - > parent_channel ,  chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_inherit_variables ( oh - > parent_channel ,  chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-03 14:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_datastore_inherit ( oh - > parent_channel ,  chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 23:51:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_unlock ( oh - > parent_channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-03 14:40:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 20:55:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( oh - > account )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_cdr_setaccount ( chan ,  oh - > account ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-29 19:04:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_set_flag ( chan - > cdr ,  AST_CDR_FLAG_ORIGINATED ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_connected_line_set_init ( & connected ,  & chan - > connected ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( cid_num )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										connected . id . number . valid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										connected . id . number . str  =  ( char  * )  cid_num ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										connected . id . number . presentation  =  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( cid_name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										connected . id . name . valid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										connected . id . name . str  =  ( char  * )  cid_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										connected . id . name . presentation  =  AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_set_connected_line ( chan ,  & connected ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ast_call ( chan ,  data ,  0 ) )  { 	/* ast_call failed... */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_NOTICE ,  " Unable to call channel %s/%s \n " ,  type ,  ( char  * ) data ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  1 ; 	/* mark success in case chan->_state is already AST_STATE_UP */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										while  ( timeout  & &  chan - > _state  ! =  AST_STATE_UP )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											struct  ast_frame  * f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											res  =  ast_waitfor ( chan ,  timeout ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-09 18:34:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( res  = =  0 )  {  /* timeout, treat it like ringing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												* outstate  =  AST_CONTROL_RINGING ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( res  <  0 )  /* error or done */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( timeout  >  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												timeout  =  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ! ast_strlen_zero ( chan - > call_forward ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 21:12:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( ! ( chan  =  ast_call_forward ( NULL ,  chan ,  NULL ,  format ,  oh ,  outstate ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-02 21:17:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											f  =  ast_read ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ! f )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												* outstate  =  AST_CONTROL_HANGUP ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( f - > frametype  = =  AST_FRAME_CONTROL )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												switch  ( f - > subclass . integer )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_RINGING : 	/* record but keep going */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													* outstate  =  f - > subclass . integer ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_BUSY : 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 22:11:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_cdr_busy ( chan - > cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													* outstate  =  f - > subclass . integer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													timeout  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-09 16:09:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_INCOMPLETE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_cdr_failed ( chan - > cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													* outstate  =  AST_CONTROL_CONGESTION ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													timeout  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_CONGESTION : 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 22:11:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_cdr_failed ( chan - > cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													* outstate  =  f - > subclass . integer ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													timeout  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_ANSWER : 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 22:11:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_cdr_answer ( chan - > cdr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													* outstate  =  f - > subclass . integer ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													timeout  =  0 ; 		/* trick to force exit from the while() */ 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-31 16:04:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												/* Ignore these */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_PROGRESS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_PROCEEDING : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_HOLD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_UNHOLD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_VIDUPDATE : 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-05 22:43:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_SRCUPDATE : 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-12 22:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_SRCCHANGE : 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_CONNECTED_LINE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_REDIRECTING : 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merge Call completion support into trunk.
From Reviewboard:
CCSS stands for Call Completion Supplementary Services. An admittedly out-of-date
overview of the architecture can be found in the file doc/CCSS_architecture.pdf
in the CCSS branch. Off the top of my head, the big differences between what is
implemented and what is in the document are as follows:
1. We did not end up modifying the Hangup application at all.
2. The document states that a single call completion monitor may be used across
   multiple calls to the same device. This proved to not be such a good idea
   when implementing protocol-specific monitors, and so we ended up using one
   monitor per-device per-call.
3. There are some configuration options which were conceived after the document
   was written. These are documented in the ccss.conf.sample that is on this
   review request.
		      
For some basic understanding of terminology used throughout this code, see the
ccss.tex document that is on this review.
This implements CCBS and CCNR in several flavors.
First up is a "generic" implementation, which can work over any channel technology
provided that the channel technology can accurately report device state. Call
completion is requested using the dialplan application CallCompletionRequest and can
be canceled using CallCompletionCancel. Device state subscriptions are used in order
to monitor the state of called parties.
Next, there is a SIP-specific implementation of call completion. This method uses the
methods outlined in draft-ietf-bliss-call-completion-06 to implement call completion
using SIP signaling. There are a few things to note here:
* The agent/monitor terminology used throughout Asterisk sometimes is the reverse of
  what is defined in the referenced draft.
* Implementation of the draft required support for SIP PUBLISH. I attempted to write
  this in a generic-enough fashion such that if someone were to want to write PUBLISH
  support for other event packages, such as dialog-state or presence, most of the effort
  would be in writing callbacks specific to the event package.
* A subportion of supporting PUBLISH reception was that we had to implement a PIDF
  parser. The PIDF support added is a bit minimal. I first wrote a validation
  routine to ensure that the PIDF document is formatted properly. The rest of the
  PIDF reading is done in-line in the call-completion-specific PUBLISH-handling
  code. In other words, while there is PIDF support here, it is not in any state
  where it could easily be applied to other event packages as is.
Finally, there are a variety of ISDN-related call completion protocols supported. These
were written by Richard Mudgett, and as such I can't really say much about their
implementation. There are notes in the CHANGES file that indicate the ISDN protocols
over which call completion is supported.
Review: https://reviewboard.asterisk.org/r/523
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-04-09 15:31:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  AST_CONTROL_CC : 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												case  - 1 : 			/* Ignore -- just stopping indications */ 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												default : 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_log ( LOG_NOTICE ,  " Don't know what to do with control frame %d \n " ,  f - > subclass . integer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												last_subclass  =  f - > subclass . integer ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_frfree ( f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-26 22:25:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Final fixups */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( oh )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! ast_strlen_zero ( oh - > context ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_copy_string ( chan - > context ,  oh - > context ,  sizeof ( chan - > context ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! ast_strlen_zero ( oh - > exten ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_copy_string ( chan - > exten ,  oh - > exten ,  sizeof ( chan - > exten ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( oh - > priority ) 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											chan - > priority  =  oh - > priority ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-10-09 14:12:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > _state  = =  AST_STATE_UP ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* outstate  =  AST_CONTROL_ANSWER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( res  < =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 20:55:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( AST_CONTROL_RINGING  = =  last_subclass )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-11 19:12:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											chan - > hangupcause  =  AST_CAUSE_NO_ANSWER ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 20:55:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! chan - > cdr  & &  ( chan - > cdr  =  ast_cdr_alloc ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-15 01:48:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_cdr_init ( chan - > cdr ,  chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 20:55:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2003-09-12 16:51:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( chan - > cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											char  tmp [ 256 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 20:55:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											snprintf ( tmp ,  sizeof ( tmp ) ,  " %s/%s " ,  type ,  ( char  * ) data ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 20:55:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_cdr_setapp ( chan - > cdr ,  " Dial " ,  tmp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-09-12 16:51:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_cdr_update ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_cdr_start ( chan - > cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_cdr_end ( chan - > cdr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* If the cause wasn't handled properly */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 20:55:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ast_cdr_disposition ( chan - > cdr ,  chan - > hangupcause ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2003-09-12 16:51:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_cdr_failed ( chan - > cdr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 20:55:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-15 01:48:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-12-16 20:55:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-09-12 16:51:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_hangup ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  chan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_request_and_dial ( const  char  * type ,  format_t  format ,  const  struct  ast_channel  * requestor ,  void  * data ,  int  timeout ,  int  * outstate ,  const  char  * cidnum ,  const  char  * cidname ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-09-22 15:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  __ast_request_and_dial ( type ,  format ,  requestor ,  data ,  timeout ,  outstate ,  cidnum ,  cidname ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-09-22 15:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-08 05:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  set_security_requirements ( const  struct  ast_channel  * requestor ,  struct  ast_channel  * out ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  ops [ 2 ] [ 2 ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ AST_OPTION_SECURE_SIGNALING ,  0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										{ AST_OPTION_SECURE_MEDIA ,  0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * r  =  ( struct  ast_channel  * )  requestor ;  /* UGLY */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * ds ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! requestor  | |  ! out )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( r ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( ds  =  ast_channel_datastore_find ( r ,  & secure_call_info ,  NULL ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										struct  ast_secure_call_store  * encrypt  =  ds - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ops [ 0 ] [ 1 ]  =  encrypt - > signaling ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ops [ 1 ] [ 1 ]  =  encrypt - > media ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( r ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( r ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( i  =  0 ;  i  <  2 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ops [ i ] [ 1 ] )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ast_channel_setoption ( out ,  ops [ i ] [ 0 ] ,  & ops [ i ] [ 1 ] ,  sizeof ( ops [ i ] [ 1 ] ) ,  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* We require a security feature, but the channel won't provide it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* We don't care if we can't clear the option on a channel that doesn't support it */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_setoption ( out ,  ops [ i ] [ 0 ] ,  & ops [ i ] [ 1 ] ,  sizeof ( ops [ i ] [ 1 ] ) ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_request ( const  char  * type ,  format_t  format ,  const  struct  ast_channel  * requestor ,  void  * data ,  int  * cause ) 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  chanlist  * chan ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-29 17:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * c ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									format_t  capabilities ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									format_t  fmt ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-26 22:25:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  foo ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									format_t  videoformat  =  format  &  AST_FORMAT_VIDEO_MASK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									format_t  textformat  =  format  &  AST_FORMAT_TEXT_MASK ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-10-26 22:25:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! cause ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cause  =  & foo ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									* cause  =  AST_CAUSE_NOTDEFINED ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-29 17:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( AST_RWLIST_RDLOCK ( & backends ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Unable to lock technology backend list \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-29 17:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_TRAVERSE ( & backends ,  chan ,  list )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-29 17:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( strcasecmp ( type ,  chan - > tech - > type ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										capabilities  =  chan - > tech - > capabilities ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-06 16:09:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										fmt  =  format  &  AST_FORMAT_AUDIO_MASK ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 17:12:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( fmt )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* We have audio - is it possible to connect the various calls to each other? 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												( Avoid  this  check  for  calls  without  audio ,  like  text + video  calls ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											res  =  ast_translator_best_choice ( & fmt ,  & capabilities ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( res  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												char  tmp1 [ 256 ] ,  tmp2 [ 256 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " No translator path exists for channel type %s (native %s) to %s \n " ,  type , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_getformatname_multiple ( tmp1 ,  sizeof ( tmp1 ) ,  chan - > tech - > capabilities ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_getformatname_multiple ( tmp2 ,  sizeof ( tmp2 ) ,  format ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 17:12:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												* cause  =  AST_CAUSE_BEARERCAPABILITY_NOTAVAIL ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 17:12:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-29 17:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! chan - > tech - > requester ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! ( c  =  chan - > tech - > requester ( type ,  capabilities  |  videoformat  |  textformat ,  requestor ,  data ,  cause ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-29 17:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-08 05:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( set_security_requirements ( requestor ,  c ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Setting security requirements failed \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											c  =  ast_channel_release ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* cause  =  AST_CAUSE_BEARERCAPABILITY_NOTAVAIL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-11-07 21:47:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* no need to generate a Newchannel event here; it is done in the channel_alloc call */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-29 17:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  c ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-26 22:25:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-29 17:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_log ( LOG_WARNING ,  " No channel type registered for '%s' \n " ,  type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									* cause  =  AST_CAUSE_NOSUCHDRIVER ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-29 17:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_call ( struct  ast_channel  * chan ,  char  * addr ,  int  timeout ) 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Place an outgoing call, but don't wait any longer than timeout ms before returning.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									   If  the  remote  end  does  not  answer  within  the  timeout ,  then  do  NOT  hang  up ,  but 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									   return  anyway .   */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Stop if we're a zombie or need a soft hangup */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-09 15:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ast_test_flag ( chan ,  AST_FLAG_ZOMBIE )  & &  ! ast_check_hangup ( chan ) )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 235635 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
  r235635 | jpeeler | 2009-12-18 16:29:51 -0600 (Fri, 18 Dec 2009) | 48 lines
  
  Correct CDR dispositions for BUSY/FAILED
  
  This patch is simple in that it reorders the disposition defines so that the fix
  for issue 12946 works properly (the default CDR disposition was changed to
  AST_CDR_NOANSWER). Also, the AST_CDR_FLAG_ORIGINATED flag was set in ast_call to
  ensure all CDR records are written.
  
  The side effects of CDR changes are scary, so I'm documenting the test cases
  performed to attempt to catch any regressions. The following tests were all
  performed using 1.4 rev 195881 vs head (235571) + patch:
  
  A calls B
  C calls B (busy)
  Hangup C
  Hangup A
  
  (Both SIP and features)
  A calls B
  A blind transfers to C
  Hangup C
  
  (Both SIP and features)
  A calls B
  A attended transfers to C
  Hangup C
  
  A calls B
  A attended transfers to C (SIP)
  C blind transfers to A (features)
  Hangup A
  
  All of the test scenario CDRs matched.
  
  The following tests were performed just with the patch to ensure proper operation
  (with unanswered=yes):
  
  exten =>s,1,Answer
  exten =>s,n,ResetCDR(w)
  exten =>s,n,ResetCDR(w)
  
  exten =>s,1,ResetCDR(w)
  exten =>s,n,ResetCDR(w)
  
  (closes issue #16180)
  Reported by: aatef
  Patches: 
        bug16180.patch uploaded by jpeeler (license 325)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@235660 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-12-18 22:51:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( chan - > cdr )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_set_flag ( chan - > cdr ,  AST_CDR_FLAG_DIALED ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 235635 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
  r235635 | jpeeler | 2009-12-18 16:29:51 -0600 (Fri, 18 Dec 2009) | 48 lines
  
  Correct CDR dispositions for BUSY/FAILED
  
  This patch is simple in that it reorders the disposition defines so that the fix
  for issue 12946 works properly (the default CDR disposition was changed to
  AST_CDR_NOANSWER). Also, the AST_CDR_FLAG_ORIGINATED flag was set in ast_call to
  ensure all CDR records are written.
  
  The side effects of CDR changes are scary, so I'm documenting the test cases
  performed to attempt to catch any regressions. The following tests were all
  performed using 1.4 rev 195881 vs head (235571) + patch:
  
  A calls B
  C calls B (busy)
  Hangup C
  Hangup A
  
  (Both SIP and features)
  A calls B
  A blind transfers to C
  Hangup C
  
  (Both SIP and features)
  A calls B
  A attended transfers to C
  Hangup C
  
  A calls B
  A attended transfers to C (SIP)
  C blind transfers to A (features)
  Hangup A
  
  All of the test scenario CDRs matched.
  
  The following tests were performed just with the patch to ensure proper operation
  (with unanswered=yes):
  
  exten =>s,1,Answer
  exten =>s,n,ResetCDR(w)
  exten =>s,n,ResetCDR(w)
  
  exten =>s,1,ResetCDR(w)
  exten =>s,n,ResetCDR(w)
  
  (closes issue #16180)
  Reported by: aatef
  Patches: 
        bug16180.patch uploaded by jpeeler (license 325)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@235660 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-12-18 22:51:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( chan - > tech - > call ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											res  =  chan - > tech - > call ( chan ,  addr ,  timeout ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-09 15:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_set_flag ( chan ,  AST_FLAG_OUTGOING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  \ brief  Transfer  a  call  to  dest ,  if  the  channel  supports  transfer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  Called  by : 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-04 23:04:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									\ arg  app_transfer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									\ arg  the  manager  interface 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								*/ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_transfer ( struct  ast_channel  * chan ,  char  * dest ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-05-14 05:33:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-05-14 05:33:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Stop if we're a zombie or need a soft hangup */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ast_test_flag ( chan ,  AST_FLAG_ZOMBIE )  & &  ! ast_check_hangup ( chan ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( chan - > tech - > transfer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											res  =  chan - > tech - > transfer ( chan ,  dest ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-05-14 05:33:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ! res ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												res  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											res  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 16:47:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-01-07 20:42:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( res  < =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 16:47:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										struct  ast_frame  * fr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  ast_waitfor ( chan ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( res  <  0  | |  ! ( fr  =  ast_read ( chan ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( fr - > frametype  = =  AST_FRAME_CONTROL  & &  fr - > subclass . integer  = =  AST_CONTROL_TRANSFER )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 16:47:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											enum  ast_control_transfer  * message  =  fr - > data . ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( * message  = =  AST_TRANSFER_SUCCESS )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												res  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_frfree ( fr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_frfree ( fr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-05-14 05:33:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								int  ast_readstring ( struct  ast_channel  * c ,  char  * s ,  int  len ,  int  timeout ,  int  ftimeout ,  char  * enders ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 07:53:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_readstring_full ( c ,  s ,  len ,  timeout ,  ftimeout ,  enders ,  - 1 ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_readstring_full ( struct  ast_channel  * c ,  char  * s ,  int  len ,  int  timeout ,  int  ftimeout ,  char  * enders ,  int  audiofd ,  int  ctrlfd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 08:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  pos  =  0 ; 	/* index in the buffer where we accumulate digits */ 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  to  =  ftimeout ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-09 20:11:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_silence_generator  * silgen  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Stop if we're a zombie or need a soft hangup */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( c ,  AST_FLAG_ZOMBIE )  | |  ast_check_hangup ( c ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! len ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 20:47:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 08:01:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										int  d ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-06-29 21:54:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( c - > stream )  { 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											d  =  ast_waitstream_full ( c ,  AST_DIGIT_ANY ,  audiofd ,  ctrlfd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_stopstream ( c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-09 20:11:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ! silgen  & &  ast_opt_transmit_silence ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												silgen  =  ast_channel_start_silence_generator ( c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											usleep ( 1000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ! d ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												d  =  ast_waitfordigit_full ( c ,  to ,  audiofd ,  ctrlfd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-09 20:11:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ! silgen  & &  ast_opt_transmit_silence ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												silgen  =  ast_channel_start_silence_generator ( c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											d  =  ast_waitfordigit_full ( c ,  to ,  audiofd ,  ctrlfd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-09 20:11:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( d  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_stop_silence_generator ( c ,  silgen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 23:21:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  AST_GETDATA_FAILED ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-09 20:11:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( d  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 23:21:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											s [ pos ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-09 20:11:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_stop_silence_generator ( c ,  silgen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 23:21:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  AST_GETDATA_TIMEOUT ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( d  = =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 23:21:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											s [ pos ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-09 20:11:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_stop_silence_generator ( c ,  silgen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 23:21:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  AST_GETDATA_INTERRUPTED ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( strchr ( enders ,  d )  & &  ( pos  = =  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											s [ pos ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-09 20:11:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_stop_silence_generator ( c ,  silgen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 23:21:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  AST_GETDATA_EMPTY_END_TERMINATED ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 23:21:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! strchr ( enders ,  d ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											s [ pos + + ]  =  d ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 23:21:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-23 06:00:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( strchr ( enders ,  d )  | |  ( pos  > =  len ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 23:21:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											s [ pos ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-09 20:11:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_stop_silence_generator ( c ,  silgen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 23:21:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  AST_GETDATA_COMPLETE ; 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										to  =  timeout ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 20:47:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											1999-12-04 21:35:07 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
									/* Never reached */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_channel_supports_html ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 20:47:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ( chan - > tech - > send_html )  ?  1  :  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-28 20:48:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_channel_sendhtml ( struct  ast_channel  * chan ,  int  subclass ,  const  char  * data ,  int  datalen ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > tech - > send_html ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  chan - > tech - > send_html ( chan ,  subclass ,  data ,  datalen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-28 20:48:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_channel_sendurl ( struct  ast_channel  * chan ,  const  char  * url ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 20:47:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_channel_sendhtml ( chan ,  AST_HTML_URL ,  url ,  strlen ( url )  +  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-01-07 14:32:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Set up translation from one channel to another */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  ast_channel_make_compatible_helper ( struct  ast_channel  * from ,  struct  ast_channel  * to ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									format_t  src ,  dst ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 14:58:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  use_slin ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-04 03:28:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-09 16:19:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* See if the channel driver can natively make these two channels compatible */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( from - > tech - > bridge  & &  from - > tech - > bridge  = =  to - > tech - > bridge  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									    ! ast_channel_setoption ( from ,  AST_OPTION_MAKE_COMPATIBLE ,  to ,  sizeof ( struct  ast_channel  * ) ,  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-12 19:19:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( from - > readformat  = =  to - > writeformat  & &  from - > writeformat  = =  to - > readformat )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Already compatible!  Moving on ... */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-01-07 14:32:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Set up translation from the 'from' channel to the 'to' channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									src  =  from - > nativeformats ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dst  =  to - > nativeformats ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 17:12:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* If there's no audio in this call, don't bother with trying to find a translation path */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( src  &  AST_FORMAT_AUDIO_MASK )  = =  0  | |  ( dst  &  AST_FORMAT_AUDIO_MASK )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-18 16:26:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_translator_best_choice ( & dst ,  & src )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No path to translate from %s to %s \n " ,  from - > name ,  to - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-04-18 16:26:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* if the best path is not 'pass through', then
 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Fix transcode_via_sln option with SIP calls and improve PLC usage.
From reviewboard:
The problem here is a bit complex, so try to bear with me...
It was noticed by a Digium customer that generic PLC (as configured in
codecs.conf) did not appear to actually be having any sort of benefit when
packet loss was introduced on an RTP stream. I reproduced this issue myself
by streaming a file across an RTP stream and dropping approx. 5% of the
RTP packets. I saw no real difference between when PLC was enabled or disabled
when using wireshark to analyze the RTP streams.
After analyzing what was going on, it became clear that one of the problems
faced was that when running my tests, the translation paths were being set
up in such a way that PLC could not possibly work as expected. To illustrate,
if packets are lost on channel A's read stream, then we expect that PLC will
be applied to channel B's write stream. The problem is that generic PLC can
only be done when there is a translation path that moves from some codec to
SLINEAR. When I would run my tests, I found that every single time, read
and write translation paths would be set up on channel A instead of channel
B. There appeared to be no real way to predict which channel the translation
paths would be set up on.
This is where Kevin swooped in to let me know about the transcode_via_sln
option in asterisk.conf. It is supposed to work by placing a read translation
path on both channels from the channel's rawreadformat to SLINEAR. It also
will place a write translation path on both channels from SLINEAR to the
channel's rawwriteformat. Using this option allows one to predictably set up
translation paths on all channels. There are two problems with this, though.
First and foremost, the transcode_via_sln option did not appear to be working
properly when I was placing a SIP call between two endpoints which did not
share any common formats. Second, even if this option were to work, for PLC
to be applied, there had to be a write translation path that would go from
some format to SLINEAR. It would not work properly if the starting format
of translation was SLINEAR.
The one-line change presented in this review request in chan_sip.c fixed the
first issue for me. The problem was that in sip_request_call, the
jointcapability of the outbound channel was being set to the format passed to
sip_request_call. This is nativeformats of the inbound channel. Because of this,
when ast_channel_make_compatible was called by app_dial, both channels already
had compatibly read and write formats. Thus, no translation path was set up at
the time. My change is to set the jointcapability of the sip_pvt created during
sip_request_call to the intersection of the inbound channel's nativeformats and
the configured peer capability that we determined during the earlier call to
create_addr. Doing this got the translation paths set up as expected when using
transcode_via_sln.
The changes presented in channel.c fixed the second issue for me. First and
foremost, when Asterisk is started, we'll read codecs.conf to see the value of
the genericplc option. If this option is set, and ast_write is called for a
frame with no data, then we will attempt to fill in the missing samples for
the frame. The implementation uses a channel datastore for maintaining the
PLC state and for creating a buffer to store PLC samples in. Even when we
receive a frame with data, we'll call plc_rx so that the PLC state will have
knowledge of the previous voice frame, which it can use as a basis for when
it comes time to actually do a PLC fill-in.
So, reviewers, now I ask for your help. First off, there's the one line change
in chan_sip that I have put in. Is it right? By my logic it seems correct, but
I'm sure someone can tell me why it is not going to work. This is probably the
change I'm least concerned about, though. What concerns me much more is the
set of changes in channel.c. First off, am I even doing it right? When I run
tests, I can clearly see that when PLC is activated, I see a significant increase
in RTP traffic where I would expect it to be. However, in my humble opinion, the
audio sounds kind of crappy whenever the PLC fill-in is done. It sounds worse to
me than when no PLC is used at all. I need someone to review the logic I have used
to be sure that I'm not misusing anything. As far as I can see my pointer arithmetic
is correct, and my use of AST_FRIENDLY_OFFSET should be correct as well, but I'm
sure someone can point out somewhere where I've done something incorrectly.
As I was writing this review request up, I decided to give the code a test run under
valgrind, and I find that for some reason, calls to plc_rx are causing some invalid
reads. Apparently I'm reading past the end of a buffer somehow. I'll have to dig around
a bit to see why that is the case. If it's obvious to someone reviewing, speak up!
Finally, I have one other proposal that is not reflected in my code review. Since
without transcode_via_sln set, one cannot predict or control where a translation
path will be up, it seems to me that the current practice of using PLC only when
transcoding to SLINEAR is not useful. I recommend that once it has been determined
that the method used in this code review is correct and works as expected, then
the code in translate.c that invokes PLC should be removed.
Review: https://reviewboard.asterisk.org/r/622/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264452 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-19 21:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									 *  transcoding  is  needed ;  if  desired ,  force  transcode  path 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  to  use  SLINEAR  between  channels ,  but  only  if  there  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  no  direct  conversion  available .  If  generic  PLC  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  desired ,  then  transcoding  via  SLINEAR  is  a  requirement 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 14:58:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									use_slin  =  ( src  = =  AST_FORMAT_SLINEAR  | |  dst  = =  AST_FORMAT_SLINEAR ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Fix transcode_via_sln option with SIP calls and improve PLC usage.
From reviewboard:
The problem here is a bit complex, so try to bear with me...
It was noticed by a Digium customer that generic PLC (as configured in
codecs.conf) did not appear to actually be having any sort of benefit when
packet loss was introduced on an RTP stream. I reproduced this issue myself
by streaming a file across an RTP stream and dropping approx. 5% of the
RTP packets. I saw no real difference between when PLC was enabled or disabled
when using wireshark to analyze the RTP streams.
After analyzing what was going on, it became clear that one of the problems
faced was that when running my tests, the translation paths were being set
up in such a way that PLC could not possibly work as expected. To illustrate,
if packets are lost on channel A's read stream, then we expect that PLC will
be applied to channel B's write stream. The problem is that generic PLC can
only be done when there is a translation path that moves from some codec to
SLINEAR. When I would run my tests, I found that every single time, read
and write translation paths would be set up on channel A instead of channel
B. There appeared to be no real way to predict which channel the translation
paths would be set up on.
This is where Kevin swooped in to let me know about the transcode_via_sln
option in asterisk.conf. It is supposed to work by placing a read translation
path on both channels from the channel's rawreadformat to SLINEAR. It also
will place a write translation path on both channels from SLINEAR to the
channel's rawwriteformat. Using this option allows one to predictably set up
translation paths on all channels. There are two problems with this, though.
First and foremost, the transcode_via_sln option did not appear to be working
properly when I was placing a SIP call between two endpoints which did not
share any common formats. Second, even if this option were to work, for PLC
to be applied, there had to be a write translation path that would go from
some format to SLINEAR. It would not work properly if the starting format
of translation was SLINEAR.
The one-line change presented in this review request in chan_sip.c fixed the
first issue for me. The problem was that in sip_request_call, the
jointcapability of the outbound channel was being set to the format passed to
sip_request_call. This is nativeformats of the inbound channel. Because of this,
when ast_channel_make_compatible was called by app_dial, both channels already
had compatibly read and write formats. Thus, no translation path was set up at
the time. My change is to set the jointcapability of the sip_pvt created during
sip_request_call to the intersection of the inbound channel's nativeformats and
the configured peer capability that we determined during the earlier call to
create_addr. Doing this got the translation paths set up as expected when using
transcode_via_sln.
The changes presented in channel.c fixed the second issue for me. First and
foremost, when Asterisk is started, we'll read codecs.conf to see the value of
the genericplc option. If this option is set, and ast_write is called for a
frame with no data, then we will attempt to fill in the missing samples for
the frame. The implementation uses a channel datastore for maintaining the
PLC state and for creating a buffer to store PLC samples in. Even when we
receive a frame with data, we'll call plc_rx so that the PLC state will have
knowledge of the previous voice frame, which it can use as a basis for when
it comes time to actually do a PLC fill-in.
So, reviewers, now I ask for your help. First off, there's the one line change
in chan_sip that I have put in. Is it right? By my logic it seems correct, but
I'm sure someone can tell me why it is not going to work. This is probably the
change I'm least concerned about, though. What concerns me much more is the
set of changes in channel.c. First off, am I even doing it right? When I run
tests, I can clearly see that when PLC is activated, I see a significant increase
in RTP traffic where I would expect it to be. However, in my humble opinion, the
audio sounds kind of crappy whenever the PLC fill-in is done. It sounds worse to
me than when no PLC is used at all. I need someone to review the logic I have used
to be sure that I'm not misusing anything. As far as I can see my pointer arithmetic
is correct, and my use of AST_FRIENDLY_OFFSET should be correct as well, but I'm
sure someone can point out somewhere where I've done something incorrectly.
As I was writing this review request up, I decided to give the code a test run under
valgrind, and I find that for some reason, calls to plc_rx are causing some invalid
reads. Apparently I'm reading past the end of a buffer somehow. I'll have to dig around
a bit to see why that is the case. If it's obvious to someone reviewing, speak up!
Finally, I have one other proposal that is not reflected in my code review. Since
without transcode_via_sln set, one cannot predict or control where a translation
path will be up, it seems to me that the current practice of using PLC only when
transcoding to SLINEAR is not useful. I recommend that once it has been determined
that the method used in this code review is correct and works as expected, then
the code in translate.c that invokes PLC should be removed.
Review: https://reviewboard.asterisk.org/r/622/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264452 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-19 21:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ( src  ! =  dst )  & &  ( ast_opt_generic_plc  | |  ast_opt_transcode_via_slin )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 14:58:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									    ( ast_translate_path_steps ( dst ,  src )  ! =  1  | |  use_slin ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-18 16:26:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										dst  =  AST_FORMAT_SLINEAR ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-07 14:32:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_set_read_format ( from ,  dst )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Unable to set read format on channel %s to %s \n " ,  from - > name ,  ast_getformatname ( dst ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-07 14:32:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_set_write_format ( to ,  dst )  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Unable to set write format on channel %s to %s \n " ,  to - > name ,  ast_getformatname ( dst ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-07 14:32:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_make_compatible ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Some callers do not check return code, and we must try to set all call legs correctly */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  rc  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Set up translation from the chan to the peer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									rc  =  ast_channel_make_compatible_helper ( chan ,  peer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( rc  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  rc ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-04-18 16:26:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Set up translation from the peer to the chan */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-01-07 14:32:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									rc  =  ast_channel_make_compatible_helper ( peer ,  chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-17 16:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-01-07 14:32:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  rc ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-09 16:55:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  __ast_channel_masquerade ( struct  ast_channel  * original ,  struct  ast_channel  * clonechan ,  struct  ast_datastore  * xfer_ds ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-20 03:16:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-01 21:31:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * final_orig ,  * final_clone ,  * base ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-28 05:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										final_orig  =  original ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										final_clone  =  clonechan ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-01 20:53:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_lock_both ( original ,  clonechan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-10 21:07:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ast_test_flag ( original ,  AST_FLAG_ZOMBIE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											| |  ast_test_flag ( clonechan ,  AST_FLAG_ZOMBIE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* Zombies! Run! */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												" Can't setup masquerade. One or both channels is dead. (%s <-- %s) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												original - > name ,  clonechan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_unlock ( clonechan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-28 05:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_unlock ( original ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  Each  of  these  channels  may  be  sitting  behind  a  channel  proxy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  ( i . e .  chan_agent )  and  if  so ,  we  don ' t  really  want  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  masquerade  it ,  but  its  proxy 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( original - > _bridge 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											& &  ( original - > _bridge  ! =  ast_bridged_channel ( original ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											& &  ( original - > _bridge - > _bridge  ! =  original ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											final_orig  =  original - > _bridge ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( clonechan - > _bridge 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											& &  ( clonechan - > _bridge  ! =  ast_bridged_channel ( clonechan ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											& &  ( clonechan - > _bridge - > _bridge  ! =  clonechan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											final_clone  =  clonechan - > _bridge ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( final_clone - > tech - > get_base_channel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											& &  ( base  =  final_clone - > tech - > get_base_channel ( final_clone ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											final_clone  =  base ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-28 05:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ( final_orig  ! =  original )  | |  ( final_clone  ! =  clonechan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  Lots  and  lots  of  deadlock  avoidance .   The  main  one  we ' re 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  competing  with  is  ast_write ( ) ,  which  locks  channels 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  recursively ,  when  working  with  a  proxy  channel . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ast_channel_trylock ( final_orig ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_channel_unlock ( clonechan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_channel_unlock ( original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* Try again */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ast_channel_trylock ( final_clone ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_channel_unlock ( final_orig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_channel_unlock ( clonechan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_channel_unlock ( original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* Try again */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_unlock ( clonechan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-09-28 05:37:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_unlock ( original ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											original  =  final_orig ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											clonechan  =  final_clone ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ast_test_flag ( original ,  AST_FLAG_ZOMBIE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												| |  ast_test_flag ( clonechan ,  AST_FLAG_ZOMBIE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* Zombies! Run! */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													" Can't setup masquerade. One or both channels is dead. (%s <-- %s) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													original - > name ,  clonechan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_channel_unlock ( clonechan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_channel_unlock ( original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-10 21:07:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2011-08-31 15:20:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-10 21:07:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-06-01 20:53:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( original  = =  clonechan )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-09 09:42:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Can't masquerade channel '%s' into itself! \n " ,  original - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( clonechan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( original ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-10 21:07:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-20 03:16:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-10 21:07:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_debug ( 1 ,  " Planning to masquerade channel %s into the structure of %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										clonechan - > name ,  original - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 23:20:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! original - > masqr  & &  ! original - > masq  & &  ! clonechan - > masq  & &  ! clonechan - > masqr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										original - > masq  =  clonechan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										clonechan - > masqr  =  original ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-09 16:55:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( xfer_ds )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_datastore_add ( original ,  xfer_ds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 20:47:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_queue_frame ( original ,  & ast_null_frame ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_queue_frame ( clonechan ,  & ast_null_frame ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_debug ( 1 ,  " Done planning to masquerade channel %s into the structure of %s \n " ,  clonechan - > name ,  original - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-20 03:16:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 23:20:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  if  ( original - > masq )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " %s is already going to masquerade as %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											original - > masq - > name ,  original - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( original - > masqr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* not yet as a previously planned masq hasn't yet happened */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " %s is already going to masquerade as %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											original - > name ,  original - > masqr - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( clonechan - > masq )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " %s is already going to masquerade as %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											clonechan - > masq - > name ,  clonechan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  {  /* (clonechan->masqr) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " %s is already going to masquerade as %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										clonechan - > name ,  clonechan - > masqr - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-20 03:16:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-10 21:07:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( clonechan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-26 21:44:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( original ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-10 21:07:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-04-20 03:16:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-09 16:55:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_channel_masquerade ( struct  ast_channel  * original ,  struct  ast_channel  * clone ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  __ast_channel_masquerade ( original ,  clone ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Copy  the  source  connected  line  information  to  the  destination  for  a  transfer . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ since  1.8 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  dest  Destination  connected  line 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  src  Source  connected  line 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ return  Nothing 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  party_connected_line_copy_transfer ( struct  ast_party_connected_line  * dest ,  const  struct  ast_party_connected_line  * src ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_party_connected_line  connected ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									connected  =  * ( ( struct  ast_party_connected_line  * )  src ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									connected . source  =  AST_CONNECTED_LINE_UPDATE_SOURCE_TRANSFER ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Make sure empty strings will be erased. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! connected . id . name . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										connected . id . name . str  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! connected . id . number . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										connected . id . number . str  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! connected . id . subaddress . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										connected . id . subaddress . str  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! connected . id . tag )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										connected . id . tag  =  " " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_connected_line_copy ( dest ,  & connected ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! Transfer masquerade connected line exchange data. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  xfer_masquerade_ds  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! New ID for the target of the transfer (Masquerade original channel) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_party_connected_line  target_id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! New ID for the transferee of the transfer (Masquerade clone channel) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_party_connected_line  transferee_id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! TRUE if the target call is held. (Masquerade original channel) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  target_held ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! TRUE if the transferee call is held. (Masquerade clone channel) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  transferee_held ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Destroy  the  transfer  connected  line  exchange  datastore  information . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ since  1.8 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  data  The  datastore  payload  to  destroy . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ return  Nothing 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  xfer_ds_destroy ( void  * data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  xfer_masquerade_ds  * ds  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_connected_line_free ( & ds - > target_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_connected_line_free ( & ds - > transferee_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_free ( ds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  const  struct  ast_datastore_info  xfer_ds_info  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. type  =  " xfer_colp " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. destroy  =  xfer_ds_destroy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_transfer_masquerade ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * target_chan , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  struct  ast_party_connected_line  * target_id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  target_held , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * transferee_chan , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  struct  ast_party_connected_line  * transferee_id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  transferee_held ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * xfer_ds ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  xfer_masquerade_ds  * xfer_colp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									xfer_ds  =  ast_datastore_alloc ( & xfer_ds_info ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! xfer_ds )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									xfer_colp  =  ast_calloc ( 1 ,  sizeof ( * xfer_colp ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! xfer_colp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_datastore_free ( xfer_ds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									party_connected_line_copy_transfer ( & xfer_colp - > target_id ,  target_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									xfer_colp - > target_held  =  target_held ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									party_connected_line_copy_transfer ( & xfer_colp - > transferee_id ,  transferee_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									xfer_colp - > transferee_held  =  transferee_held ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									xfer_ds - > data  =  xfer_colp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									res  =  __ast_channel_masquerade ( target_chan ,  transferee_chan ,  xfer_ds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_datastore_free ( xfer_ds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief this function simply changes the name of the channel and issues a manager_event
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *          with  out  unlinking  and  linking  the  channel  from  the  ao2_container .   This  should 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *          only  be  used  when  the  channel  has  already  been  unlinked  from  the  ao2_container . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  __ast_change_name_nolink ( struct  ast_channel  * chan ,  const  char  * newname ) 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_manager_event ( chan ,  EVENT_FLAG_CALL ,  " Rename " ,  " Channel: %s \r \n Newname: %s \r \n Uniqueid: %s \r \n " ,  chan - > name ,  newname ,  chan - > uniqueid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-01 23:05:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_string_field_set ( chan ,  name ,  newname ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_change_name ( struct  ast_channel  * chan ,  const  char  * newname ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* We must re-link, as the hash value will change here. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ao2_unlink ( channels ,  chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									__ast_change_name_nolink ( chan ,  newname ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ao2_link ( channels ,  chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 17:23:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channel_inherit_variables ( const  struct  ast_channel  * parent ,  struct  ast_channel  * child ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_var_t  * current ,  * newvar ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-03 19:25:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  char  * varname ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 17:23:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_LIST_TRAVERSE ( & parent - > varshead ,  current ,  entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  vartype  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										varname  =  ast_var_full_name ( current ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! varname ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( varname [ 0 ]  = =  ' _ ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											vartype  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( varname [ 1 ]  = =  ' _ ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												vartype  =  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  ( vartype )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											newvar  =  ast_var_assign ( & varname [ 1 ] ,  ast_var_value ( current ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( newvar )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-01 21:50:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												AST_LIST_INSERT_TAIL ( & child - > varshead ,  newvar ,  entries ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_debug ( 1 ,  " Copying soft-transferable variable %s. \n " ,  ast_var_name ( newvar ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 17:23:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  2 : 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-03 20:30:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											newvar  =  ast_var_assign ( varname ,  ast_var_value ( current ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 17:23:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( newvar )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-01 21:50:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												AST_LIST_INSERT_TAIL ( & child - > varshead ,  newvar ,  entries ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_debug ( 1 ,  " Copying hard-transferable variable %s. \n " ,  ast_var_name ( newvar ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 17:23:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_debug ( 1 ,  " Not copying variable %s. \n " ,  ast_var_name ( current ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-08 17:23:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  \ brief  Clone  channel  variables  from  ' clone '  channel  into  ' original '  channel 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  All  variables  except  those  related  to  app_groupcount  are  cloned . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  Variables  are  actually  _removed_  from  ' clone '  channel ,  presumably 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  because  it  will  subsequently  be  destroyed . 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								  \ note  Assumes  locks  will  be  in  place  on  both  channels  when  called . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*/ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  clone_variables ( struct  ast_channel  * original ,  struct  ast_channel  * clonechan ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-02 02:07:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-19 18:31:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_var_t  * current ,  * newvar ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-02 02:07:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Append variables from clone channel into original channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* XXX Is this always correct?  We have to in order to keep MACROS working XXX */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( AST_LIST_FIRST ( & clonechan - > varshead ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_LIST_APPEND_LIST ( & original - > varshead ,  & clonechan - > varshead ,  entries ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-19 18:31:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* then, dup the varshead list into the clone */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_LIST_TRAVERSE ( & original - > varshead ,  current ,  entries )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										newvar  =  ast_var_assign ( current - > name ,  current - > value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( newvar ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											AST_LIST_INSERT_TAIL ( & clonechan - > varshead ,  newvar ,  entries ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-19 18:31:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-02 02:07:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* return the oldest of two linkedids.  linkedid is derived from
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   uniqueid  which  is  formed  like  this :  [ systemname - ] ctime . seq 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   The  systemname ,  and  the  dash  are  optional ,  followed  by  the  epoch 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   time  followed  by  an  integer  sequence .   Note  that  this  is  not  a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   decimal  number ,  since  1.2  is  less  than  1.11  in  uniqueid  land . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   To  compare  two  uniqueids ,  we  parse  out  the  integer  values  of  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   time  and  the  sequence  numbers  and  compare  them ,  with  time  trumping 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								   sequence . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  const  char  * oldest_linkedid ( const  char  * a ,  const  char  * b ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * satime ,  * saseq ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * sbtime ,  * sbseq ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * dash ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  atime ,  aseq ,  btime ,  bseq ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ast_strlen_zero ( a ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  b ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ast_strlen_zero ( b ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  a ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									satime  =  a ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sbtime  =  b ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* jump over the system name */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( dash  =  strrchr ( satime ,  ' - ' ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										satime  =  dash + 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( dash  =  strrchr ( sbtime ,  ' - ' ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sbtime  =  dash + 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* the sequence comes after the '.' */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									saseq  =  strchr ( satime ,  ' . ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sbseq  =  strchr ( sbtime ,  ' . ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! saseq  | |  ! sbseq ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									saseq + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									sbseq + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* convert it all to integers */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									atime  =  atoi ( satime ) ;  /* note that atoi is ignoring the '.' after the time string */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									btime  =  atoi ( sbtime ) ;  /* note that atoi is ignoring the '.' after the time string */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									aseq  =  atoi ( saseq ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									bseq  =  atoi ( sbseq ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* and finally compare */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( atime  = =  btime )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ( aseq  <  bseq )  ?  a  :  b ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  ( atime  <  btime )  ?  a  :  b ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! Set the channel's linkedid to the given string, and also check to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *   see  if  the  channel ' s  old  linkedid  is  now  being  retired  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  ast_channel_change_linkedid ( struct  ast_channel  * chan ,  const  char  * linkedid ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* if the linkedid for this channel is being changed from something, check... */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_strlen_zero ( chan - > linkedid )  & &  0  ! =  strcmp ( chan - > linkedid ,  linkedid ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_cel_check_retire_linkedid ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_string_field_set ( chan ,  linkedid ,  linkedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  \ brief  Propagate  the  oldest  linkedid  between  associated  channels 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_channel_set_linkgroup ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char *  linkedid = NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * bridged ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									linkedid  =  oldest_linkedid ( chan - > linkedid ,  peer - > linkedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									linkedid  =  oldest_linkedid ( linkedid ,  chan - > uniqueid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									linkedid  =  oldest_linkedid ( linkedid ,  peer - > uniqueid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan - > _bridge )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										bridged  =  ast_bridged_channel ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( bridged  ! =  peer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											linkedid  =  oldest_linkedid ( linkedid ,  bridged - > linkedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											linkedid  =  oldest_linkedid ( linkedid ,  bridged - > uniqueid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( peer - > _bridge )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										bridged  =  ast_bridged_channel ( peer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( bridged  ! =  chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											linkedid  =  oldest_linkedid ( linkedid ,  bridged - > linkedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											linkedid  =  oldest_linkedid ( linkedid ,  bridged - > uniqueid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* just in case setting a stringfield to itself causes problems */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									linkedid  =  ast_strdupa ( linkedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_change_linkedid ( chan ,  linkedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_change_linkedid ( peer ,  linkedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( chan - > _bridge )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										bridged  =  ast_bridged_channel ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( bridged  ! =  peer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_change_linkedid ( bridged ,  linkedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( peer - > _bridge )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										bridged  =  ast_bridged_channel ( peer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( bridged  ! =  chan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_change_linkedid ( bridged ,  linkedid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* copy accountcode and peeraccount across during a link */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  ast_set_owners_and_peers ( struct  ast_channel  * chan1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
																	 struct  ast_channel  * chan2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_strlen_zero ( chan1 - > accountcode )  & &  ast_strlen_zero ( chan2 - > peeraccount ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_DEBUG ,  " setting peeraccount to %s for %s from data on channel %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												chan1 - > accountcode ,  chan2 - > name ,  chan1 - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_set ( chan2 ,  peeraccount ,  chan1 - > accountcode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_strlen_zero ( chan2 - > accountcode )  & &  ast_strlen_zero ( chan1 - > peeraccount ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_DEBUG ,  " setting peeraccount to %s for %s from data on channel %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												chan2 - > accountcode ,  chan1 - > name ,  chan2 - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_set ( chan1 ,  peeraccount ,  chan2 - > accountcode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_strlen_zero ( chan1 - > peeraccount )  & &  ast_strlen_zero ( chan2 - > accountcode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_DEBUG ,  " setting accountcode to %s for %s from data on channel %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												chan1 - > peeraccount ,  chan2 - > name ,  chan1 - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_set ( chan2 ,  accountcode ,  chan1 - > peeraccount ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_strlen_zero ( chan2 - > peeraccount )  & &  ast_strlen_zero ( chan1 - > accountcode ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_DEBUG ,  " setting accountcode to %s for %s from data on channel %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												chan2 - > peeraccount ,  chan1 - > name ,  chan2 - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_set ( chan1 ,  accountcode ,  chan2 - > peeraccount ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( 0  ! =  strcmp ( chan1 - > accountcode ,  chan2 - > peeraccount ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_DEBUG ,  " changing peeraccount from %s to %s on %s to match channel %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												chan2 - > peeraccount ,  chan1 - > peeraccount ,  chan2 - > name ,  chan1 - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_set ( chan2 ,  peeraccount ,  chan1 - > accountcode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( 0  ! =  strcmp ( chan2 - > accountcode ,  chan1 - > peeraccount ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_DEBUG ,  " changing peeraccount from %s to %s on %s to match channel %s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												chan1 - > peeraccount ,  chan2 - > peeraccount ,  chan1 - > name ,  chan2 - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_set ( chan1 ,  peeraccount ,  chan2 - > accountcode ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-22 20:11:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ pre  chan  is  locked 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  report_new_callerid ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-22 20:11:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  pres ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pres  =  ast_party_id_presentation ( & chan - > caller . id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_manager_event ( chan ,  EVENT_FLAG_CALL ,  " NewCallerid " , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										" Channel: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" CallerIDNum: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" CallerIDName: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" Uniqueid: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" CID-CallingPres: %d (%s) \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										S_COR ( chan - > caller . id . number . valid ,  chan - > caller . id . number . str ,  " " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										S_COR ( chan - > caller . id . name . valid ,  chan - > caller . id . name . str ,  " " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > uniqueid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pres , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_describe_caller_presentation ( pres ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-22 20:11:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-09 16:55:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Transfer  COLP  between  target  and  transferee  channels . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ since  1.8 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  transferee  Transferee  channel  to  exchange  connected  line  information . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  colp  Connected  line  information  to  exchange . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ return  Nothing 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  masquerade_colp_transfer ( struct  ast_channel  * transferee ,  struct  xfer_masquerade_ds  * colp ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_control_read_action_payload  * frame_payload ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  payload_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  frame_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  connected_line_data [ 1024 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-09 16:55:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Release any hold on the target. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( colp - > target_held )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_queue_control ( transferee ,  AST_CONTROL_UNHOLD ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Since  transferee  may  not  actually  be  bridged  to  another  channel , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  there  is  no  way  for  us  to  queue  a  frame  so  that  its  connected 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  line  status  will  be  updated .   Instead ,  we  use  the  somewhat 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  hackish  approach  of  using  a  special  control  frame  type  that 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  instructs  ast_read ( )  to  perform  a  specific  action .   In  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  case ,  the  frame  we  queue  tells  ast_read ( )  to  call  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  connected  line  interception  macro  configured  for  transferee . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									payload_size  =  ast_connected_line_build_data ( connected_line_data , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sizeof ( connected_line_data ) ,  & colp - > target_id ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( payload_size  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame_size  =  payload_size  +  sizeof ( * frame_payload ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame_payload  =  alloca ( frame_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame_payload - > action  =  AST_FRAME_READ_ACTION_CONNECTED_LINE_MACRO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										frame_payload - > payload_size  =  payload_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										memcpy ( frame_payload - > payload ,  connected_line_data ,  payload_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_queue_control_data ( transferee ,  AST_CONTROL_READ_ACTION ,  frame_payload , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											frame_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  In  addition  to  queueing  the  read  action  frame  so  that  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  connected  line  info  on  transferee  will  be  updated ,  we  also  are 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  going  to  queue  a  plain  old  connected  line  update  on  transferee  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  update  the  target . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_queue_connected_line_update ( transferee ,  & colp - > transferee_id ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Masquerade  a  channel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ note  Assumes  _NO_  channels  and  _NO_  channel  pvt ' s  are  locked .   If  a  channel  is  locked  while  calling 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *        this  function ,  it  invalidates  our  channel  container  locking  order .   All  channels 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *        must  be  unlocked  before  it  is  permissible  to  lock  the  channels '  ao2  container . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-06 22:17:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_do_masquerade ( struct  ast_channel  * original ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									format_t  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res = 0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-07-09 10:57:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  origstate ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-22 15:47:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  visible_indication ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_frame  * current ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  struct  ast_channel_tech  * t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									void  * t_pvt ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									union  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										struct  ast_party_dialed  dialed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										struct  ast_party_caller  caller ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										struct  ast_party_connected_line  connected ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										struct  ast_party_redirecting  redirecting ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  exchange ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * clonechan ,  * chans [ 2 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-16 17:53:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * bridged ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-30 14:37:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_cdr  * cdr ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-09 16:55:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * xfer_ds ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  xfer_masquerade_ds  * xfer_colp ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									format_t  rformat  =  original - > readformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									format_t  wformat  =  original - > writeformat ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-03 21:27:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  newn [ AST_CHANNEL_NAME ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  orig [ AST_CHANNEL_NAME ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  masqn [ AST_CHANNEL_NAME ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  zombn [ AST_CHANNEL_NAME ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:23:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-28 20:14:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* XXX This operation is a bit odd.  We're essentially putting the guts of
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  the  clone  channel  into  the  original  channel .   Start  by  killing  off  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  original  channel ' s  backend .   While  the  features  are  nice ,  which  is  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  reason  we ' re  keeping  it ,  it ' s  still  awesomely  weird .  XXX  */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* The reasoning for the channels ao2_container lock here is complex.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  In  order  to  check  for  a  race  condition ,  the  original  channel  must 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  be  locked .   If  it  is  determined  that  the  masquerade  should  proceed 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  the  original  channel  can  absolutely  not  be  unlocked  until  the  end 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  of  the  function .   Since  after  determining  the  masquerade  should 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  continue  requires  the  channels  to  be  unlinked  from  the  ao2_container , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  the  container  lock  must  be  held  first  to  achieve  proper  locking  order . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ao2_lock ( channels ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-07-30 23:56:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* lock the original channel to determine if the masquerade is required or not */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-07-30 23:56:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  This  checks  to  see  if  the  masquerade  has  already  happened  or 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  not .   There  is  a  race  condition  that  exists  for  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  function .   Since  all  pvt  and  channel  locks  must  be  let  go 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  before  calling  do_masquerade ,  it  is  possible  that  it  could  be 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  called  multiple  times  for  the  same  channel .   This  check 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  verifies  whether  or  not  the  masquerade  has  already  been 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  completed  by  another  thread . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-30 15:25:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									while  ( ( clonechan  =  original - > masq )  & &  ast_channel_trylock ( clonechan ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-30 23:56:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  A  masq  is  needed  but  we  could  not  get  the  clonechan  lock 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  immediately .   Since  this  function  already  holds  the  global 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  container  lock ,  unlocking  original  for  deadlock  avoidance 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  will  not  result  in  any  sort  of  masquerade  race  condition .   If 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  masq  is  called  by  a  different  thread  while  this  happens ,  it 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  will  be  stuck  waiting  until  we  unlock  the  container . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										CHANNEL_DEADLOCK_AVOIDANCE ( original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-07-30 23:56:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  A  final  masq  check  must  be  done  after  deadlock  avoidance  for 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  clonechan  above  or  we  could  get  a  double  masq .   This  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  posible  with  ast_hangup  at  least . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! clonechan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* masq already completed by another thread, or never needed to be done to begin with */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-30 15:25:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ao2_unlock ( channels ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-30 23:56:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-07-30 15:25:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-09 16:55:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Get any transfer masquerade connected line exchange data. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									xfer_ds  =  ast_channel_datastore_find ( original ,  & xfer_ds_info ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( xfer_ds )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_datastore_remove ( original ,  xfer_ds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										xfer_colp  =  xfer_ds - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										xfer_colp  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Release  any  hold  on  the  transferee  channel  before  proceeding 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  with  the  masquerade . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( xfer_colp  & &  xfer_colp - > transferee_held )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_indicate ( clonechan ,  AST_CONTROL_UNHOLD ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* clear the masquerade channels */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									original - > masq  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > masqr  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* unlink from channels container as name (which is the hash value) will change */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ao2_unlink ( channels ,  original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ao2_unlink ( channels ,  clonechan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_debug ( 4 ,  " Actually Masquerading %s(%d) into the structure of %s(%d) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										clonechan - > name ,  clonechan - > _state ,  original - > name ,  original - > _state ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-22 15:47:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Stop  any  visible  indiction  on  the  original  channel  so  we  can 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  transfer  it  to  the  clonechan  taking  the  original ' s  place . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									visible_indication  =  original - > visible_indication ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_indicate ( original ,  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									chans [ 0 ]  =  clonechan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									chans [ 1 ]  =  original ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-22 15:47:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_manager_event_multichan ( EVENT_FLAG_CALL ,  " Masquerade " ,  2 ,  chans , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" Clone: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" CloneState: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" Original: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" OriginalState: %s \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										clonechan - > name ,  ast_state2str ( clonechan - > _state ) ,  original - > name ,  ast_state2str ( original - > _state ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-08-11 21:31:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Having remembered the original read/write formats, we turn off any translation on either
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									   one  */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									free_translation ( clonechan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									free_translation ( original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Save the original name */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-06-05 16:32:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_copy_string ( orig ,  original - > name ,  sizeof ( orig ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Save the new name */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_copy_string ( newn ,  clonechan - > name ,  sizeof ( newn ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Create the masq name */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									snprintf ( masqn ,  sizeof ( masqn ) ,  " %s<MASQ> " ,  newn ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Mangle the name of the clone channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									__ast_change_name_nolink ( clonechan ,  masqn ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 14:29:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Copy the name from the clone channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									__ast_change_name_nolink ( original ,  newn ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-03 14:29:17 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* share linked id's */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_set_linkgroup ( original ,  clonechan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Swap the technologies */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									t  =  original - > tech ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									original - > tech  =  clonechan - > tech ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > tech  =  t ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-03-30 14:37:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Swap the cdrs */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									cdr  =  original - > cdr ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									original - > cdr  =  clonechan - > cdr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > cdr  =  cdr ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-03-30 14:37:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									t_pvt  =  original - > tech_pvt ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									original - > tech_pvt  =  clonechan - > tech_pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > tech_pvt  =  t_pvt ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Swap the alertpipes */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( i  =  0 ;  i  <  2 ;  i + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										x  =  original - > alertpipe [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										original - > alertpipe [ i ]  =  clonechan - > alertpipe [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										clonechan - > alertpipe [ i ]  =  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-05 20:14:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Swap  the  readq ' s .   The  end  result  should  be  this : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   1 )  All  frames  should  be  on  the  new  ( original )  channel . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   2 )  Any  frames  that  were  already  on  the  new  channel  before  this 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *      masquerade  need  to  be  at  the  end  of  the  readq ,  after  all  of  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *      frames  on  the  old  ( clone )  channel . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *   3 )  The  alertpipe  needs  to  get  poked  for  every  frame  that  was  already 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *      on  the  new  channel ,  since  we  are  now  using  the  alert  pipe  from  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *      old  ( clone )  channel . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_LIST_HEAD_NOLOCK ( ,  ast_frame )  tmp_readq ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_LIST_HEAD_SET_NOLOCK ( & tmp_readq ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_LIST_APPEND_LIST ( & tmp_readq ,  & original - > readq ,  frame_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_LIST_APPEND_LIST ( & original - > readq ,  & clonechan - > readq ,  frame_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-05 20:14:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										while  ( ( current  =  AST_LIST_REMOVE_HEAD ( & tmp_readq ,  frame_list ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											AST_LIST_INSERT_TAIL ( & original - > readq ,  current ,  frame_list ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-05 20:14:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( original - > alertpipe [ 1 ]  >  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												int  poke  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-11-02 18:52:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( write ( original - > alertpipe [ 1 ] ,  & poke ,  sizeof ( poke ) )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_log ( LOG_WARNING ,  " write() failed: %s \n " ,  strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-05 20:14:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Swap the raw formats */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									x  =  original - > rawreadformat ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									original - > rawreadformat  =  clonechan - > rawreadformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > rawreadformat  =  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									x  =  original - > rawwriteformat ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									original - > rawwriteformat  =  clonechan - > rawwriteformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > rawwriteformat  =  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-08-14 19:18:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									clonechan - > _softhangup  =  AST_SOFTHANGUP_DEV ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-07-09 10:57:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* And of course, so does our current state.  Note we need not
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									   call  ast_setstate  since  the  event  manager  doesn ' t  really  consider 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									   these  separate .   We  do  this  early  so  that  the  clone  has  the  proper 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									   state  of  the  original  channel .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									origstate  =  original - > _state ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									original - > _state  =  clonechan - > _state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > _state  =  origstate ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-07-09 10:57:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( clonechan - > tech - > fixup  & &  clonechan - > tech - > fixup ( original ,  clonechan ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Fixup failed on channel %s, strange things may happen. \n " ,  clonechan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Start by disconnecting the original's physical side */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( clonechan - > tech - > hangup  & &  clonechan - > tech - > hangup ( clonechan ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Hangup failed!  Strange things may happen! \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										goto  done ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-03 21:27:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-05-25 16:23:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  We  just  hung  up  the  physical  side  of  the  channel .   Set  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  new  zombie  to  use  the  kill  channel  driver  for  safety . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > tech  =  & ast_kill_tech ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Mangle the name of the clone channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									snprintf ( zombn ,  sizeof ( zombn ) ,  " %s<ZOMBIE> " ,  orig ) ;  /* quick, hide the brains! */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									__ast_change_name_nolink ( clonechan ,  zombn ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Update the type. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-31 21:27:21 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									t_pvt  =  original - > monitor ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									original - > monitor  =  clonechan - > monitor ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > monitor  =  t_pvt ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-03 21:27:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-21 22:30:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Keep the same language.  */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_string_field_set ( original ,  language ,  clonechan - > language ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Copy the FD's other than the generator fd */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( x  =  0 ;  x  <  AST_MAX_FDS ;  x + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-30 03:13:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( x  ! =  AST_GENERATOR_FD ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_channel_set_fd ( original ,  x ,  clonechan - > fds [ x ] ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-06-29 23:23:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-28 18:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_app_group_update ( clonechan ,  original ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-04-25 19:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-10 23:29:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Move data stores over */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( AST_LIST_FIRST ( & clonechan - > datastores ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-13 21:40:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										struct  ast_datastore  * ds ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 20:04:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* We use a safe traversal here because some fixup routines actually
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  remove  the  datastore  from  the  list  and  free  them . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										AST_LIST_TRAVERSE_SAFE_BEGIN ( & clonechan - > datastores ,  ds ,  entry )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-13 21:40:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ds - > info - > chan_fixup ) 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ds - > info - > chan_fixup ( ds - > data ,  clonechan ,  original ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-13 21:40:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-17 20:04:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_LIST_TRAVERSE_SAFE_END ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-19 22:26:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										AST_LIST_APPEND_LIST ( & original - > datastores ,  & clonechan - > datastores ,  entry ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-13 21:40:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-10 23:29:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_autochan_new_channel ( clonechan ,  original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									clone_variables ( original ,  clonechan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-20 15:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Presense of ADSI capable CPE follows clone */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									original - > adsicpe  =  clonechan - > adsicpe ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Bridge remains the same */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* CDR fields remain the same */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Application and data remain the same */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-27 21:21:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Clone exception  becomes real one, as with fdno */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-01-14 18:03:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_set_flag ( original ,  ast_test_flag ( clonechan ,  AST_FLAG_EXCEPTION  |  AST_FLAG_OUTGOING ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									original - > fdno  =  clonechan - > fdno ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Schedule context remains the same */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Stream stuff stays the same */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-27 21:21:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Keep the original state.  The fixup code will need to work with it most likely */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  Just  swap  the  whole  structures ,  nevermind  the  allocations , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  they ' ll  work  themselves  out . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									exchange . dialed  =  original - > dialed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									original - > dialed  =  clonechan - > dialed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > dialed  =  exchange . dialed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									exchange . caller  =  original - > caller ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									original - > caller  =  clonechan - > caller ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > caller  =  exchange . caller ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-22 20:11:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									exchange . connected  =  original - > connected ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									original - > connected  =  clonechan - > connected ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > connected  =  exchange . connected ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									exchange . redirecting  =  original - > redirecting ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									original - > redirecting  =  clonechan - > redirecting ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									clonechan - > redirecting  =  exchange . redirecting ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-03 21:27:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									report_new_callerid ( original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-06-29 23:23:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Restore original timing file descriptor */ 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_set_fd ( original ,  AST_TIMING_FD ,  original - > timingfd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-03 21:27:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Our native formats are different now */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									original - > nativeformats  =  clonechan - > nativeformats ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-03 21:27:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-04-27 21:21:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Context, extension, priority, app data, jump table,  remain the same */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* pvt switches.  pbx stays the same, as does next */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-03 21:27:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Set the write format */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-06 22:17:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_set_write_format ( original ,  wformat ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Set the read format */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-06 22:17:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_set_read_format ( original ,  rformat ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:23:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Copy the music class */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_string_field_set ( original ,  musicclass ,  clonechan - > musicclass ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-10 04:23:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* copy over accuntcode and set peeraccount across the bridge */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_string_field_set ( original ,  accountcode ,  S_OR ( clonechan - > accountcode ,  " " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( original - > _bridge )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* XXX - should we try to lock original->_bridge here? */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_string_field_set ( original - > _bridge ,  peeraccount ,  S_OR ( clonechan - > accountcode ,  " " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_cel_report_event ( original ,  AST_CEL_BRIDGE_UPDATE ,  NULL ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_debug ( 1 ,  " Putting channel %s in %s/%s formats \n " ,  original - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_getformatname ( wformat ) ,  ast_getformatname ( rformat ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Okay.  Last thing is to let the channel driver know about all this mess, so he
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									   can  fix  up  everything  as  best  as  possible  */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( original - > tech - > fixup )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( original - > tech - > fixup ( clonechan ,  original ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Channel for type '%s' could not fixup channel %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-01 23:05:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												original - > tech - > type ,  original - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											res  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											goto  done ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Channel type '%s' does not have a fixup routine (for %s)!  Bad things may happen. \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-01 23:05:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											original - > tech - > type ,  original - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-03 18:44:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  If  an  indication  is  currently  playing ,  maintain  it  on  the  channel  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  that  is  taking  the  place  of  original  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  This  is  needed  because  the  masquerade  is  swapping  out  in  the  internals 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  of  this  channel ,  and  the  new  channel  private  data  needs  to  be  made 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  aware  of  the  current  visible  indication  ( RINGING ,  CONGESTION ,  etc . ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-22 15:47:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( visible_indication )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_indicate ( original ,  visible_indication ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-15 14:40:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-02-19 20:07:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									   a  zombie  so  nothing  tries  to  touch  it .   If  it ' s  already  been  marked  as  a 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									   zombie ,  then  free  it  now  ( since  it  already  is  considered  invalid ) .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( clonechan ,  AST_FLAG_ZOMBIE ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_debug ( 1 ,  " Destroying channel clone '%s' \n " ,  clonechan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( clonechan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_manager_event ( clonechan ,  EVENT_FLAG_CALL ,  " Hangup " , 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											" Channel: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" Uniqueid: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" Cause: %d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											" Cause-txt: %s \r \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											clonechan - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											clonechan - > uniqueid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											clonechan - > hangupcause , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_cause2str ( clonechan - > hangupcause ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										clonechan  =  ast_channel_release ( clonechan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-02-19 20:07:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-10 19:35:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_debug ( 1 ,  " Released clone lock on '%s' \n " ,  clonechan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_set_flag ( clonechan ,  AST_FLAG_ZOMBIE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_queue_frame ( clonechan ,  & ast_null_frame ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-02-19 20:07:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-03 21:27:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Signal any blocker */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( original ,  AST_FLAG_BLOCKING ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pthread_kill ( original - > blocker ,  SIGURG ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_debug ( 1 ,  " Done Masquerading %s (%d) \n " ,  original - > name ,  original - > _state ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-08-16 17:53:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ( bridged  =  ast_bridged_channel ( original ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_lock ( bridged ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_indicate ( bridged ,  AST_CONTROL_SRCCHANGE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( bridged ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_indicate ( original ,  AST_CONTROL_SRCCHANGE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-09 16:55:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( xfer_colp )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  After  the  masquerade ,  the  original  channel  pointer  actually 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  points  to  the  new  transferee  channel  and  the  bridged  channel 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  is  still  the  intended  transfer  target  party . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										masquerade_colp_transfer ( original ,  xfer_colp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								done : 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-09 16:55:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( xfer_ds )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_datastore_free ( xfer_ds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-07 22:58:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* it is possible for the clone channel to disappear during this */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( clonechan )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( clonechan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ao2_link ( channels ,  clonechan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ao2_link ( channels ,  original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ao2_link ( channels ,  original ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-16 17:53:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-20 22:21:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ao2_unlock ( channels ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-09 22:46:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-25 19:33:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_set_callerid ( struct  ast_channel  * chan ,  const  char  * cid_num ,  const  char  * cid_name ,  const  char  * cid_ani ) 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-29 00:28:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-25 19:33:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( cid_num )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > caller . id . number . valid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_free ( chan - > caller . id . number . str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > caller . id . number . str  =  ast_strdup ( cid_num ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-02 00:58:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-25 19:33:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( cid_name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > caller . id . name . valid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_free ( chan - > caller . id . name . str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > caller . id . name . str  =  ast_strdup ( cid_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-02 00:58:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-11-25 19:33:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( cid_ani )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 16:58:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > caller . ani . number . valid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_free ( chan - > caller . ani . number . str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > caller . ani . number . str  =  ast_strdup ( cid_ani ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 15:04:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_cdr_setcid ( chan - > cdr ,  chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-22 20:11:04 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									report_new_callerid ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-11-29 00:28:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channel_set_caller ( struct  ast_channel  * chan ,  const  struct  ast_party_caller  * caller ,  const  struct  ast_set_party_caller  * update ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( & chan - > caller  = =  caller )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't set to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_caller_set ( & chan - > caller ,  caller ,  update ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_channel_set_caller_event ( struct  ast_channel  * chan ,  const  struct  ast_party_caller  * caller ,  const  struct  ast_set_party_caller  * update ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-24 21:38:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  char  * pre_set_number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * pre_set_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( & chan - > caller  = =  caller )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't set to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-24 21:38:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pre_set_number  = 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										S_COR ( chan - > caller . id . number . valid ,  chan - > caller . id . number . str ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pre_set_name  =  S_COR ( chan - > caller . id . name . valid ,  chan - > caller . id . name . str ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_caller_set ( & chan - > caller ,  caller ,  update ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-24 21:38:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( S_COR ( chan - > caller . id . number . valid ,  chan - > caller . id . number . str ,  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											! =  pre_set_number 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										| |  S_COR ( chan - > caller . id . name . valid ,  chan - > caller . id . name . str ,  NULL ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											! =  pre_set_name )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* The caller id name or number changed. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										report_new_callerid ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-29 17:08:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan - > cdr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_cdr_setcid ( chan - > cdr ,  chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-08-19 00:33:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_setstate ( struct  ast_channel  * chan ,  enum  ast_channel_state  state ) 
							 
						 
					
						
							
								
									
										
										
										
											2002-09-10 20:48:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-01 22:28:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  oldstate  =  chan - > _state ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-07-25 17:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  name [ AST_CHANNEL_NAME ] ,  * dashptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-01 22:28:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( oldstate  = =  state ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-07-25 17:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_copy_string ( name ,  chan - > name ,  sizeof ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( dashptr  =  strrchr ( name ,  ' - ' ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* dashptr  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-01 22:28:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									chan - > _state  =  state ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-12-12 16:55:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  for  this  channel  is  using  the  callback  method  for  device  state .  If  we  pass  in  an  actual  state  here 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  we  override  what  they  are  saying  the  state  is  and  things  go  amuck .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_devstate_changed_literal ( AST_DEVICE_UNKNOWN ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-11-07 21:47:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* setstate used to conditionally report Newchannel; this is no more */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_manager_event ( chan ,  EVENT_FLAG_CALL ,  " Newstate " , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										" Channel: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" ChannelState: %d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" ChannelStateDesc: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" CallerIDNum: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" CallerIDName: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-25 17:06:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										" ConnectedLineNum: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" ConnectedLineName: %s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										" Uniqueid: %s \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										chan - > name ,  chan - > _state ,  ast_state2str ( chan - > _state ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										S_COR ( chan - > caller . id . number . valid ,  chan - > caller . id . number . str ,  " " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										S_COR ( chan - > caller . id . name . valid ,  chan - > caller . id . name . str ,  " " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2011-05-25 17:06:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										S_COR ( chan - > connected . id . number . valid ,  chan - > connected . id . number . str ,  " " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										S_COR ( chan - > connected . id . name . valid ,  chan - > connected . id . name . str ,  " " ) , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										chan - > uniqueid ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-01 22:28:33 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Find bridged channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-23 12:19:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_bridged_channel ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * bridged ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									bridged  =  chan - > _bridge ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( bridged  & &  bridged - > tech - > bridged_channel ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-04 06:47:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										bridged  =  bridged - > tech - > bridged_channel ( chan ,  bridged ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-23 12:19:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  bridged ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  bridge_playfile ( struct  ast_channel  * chan ,  struct  ast_channel  * peer ,  const  char  * sound ,  int  remain ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-05-03 02:02:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-24 05:18:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  min  =  0 ,  sec  =  0 ,  check ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-05-06 22:29:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									check  =  ast_autoservice_start ( peer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( check ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-05-06 22:29:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-05-03 02:02:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( remain  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( remain  /  60  >  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											min  =  remain  /  60 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											sec  =  remain  %  60 ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-05-03 02:02:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											sec  =  remain ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-05-15 04:48:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! strcmp ( sound , " timeleft " ) )  { 	/* Queue support */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-17 23:18:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_stream_and_wait ( chan ,  " vm-youhave " ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-05-03 02:02:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( min )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 20:47:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_say_number ( chan ,  min ,  AST_DIGIT_ANY ,  chan - > language ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-17 23:18:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_stream_and_wait ( chan ,  " queue-minutes " ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2004-05-03 02:02:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( sec )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 20:47:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_say_number ( chan ,  sec ,  AST_DIGIT_ANY ,  chan - > language ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-17 23:18:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_stream_and_wait ( chan ,  " queue-seconds " ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2004-05-03 02:02:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-17 23:18:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_stream_and_wait ( chan ,  sound ,  " " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2004-05-06 22:29:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 20:39:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_autoservice_stop ( peer ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-13 18:27:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  enum  ast_bridge_result  ast_generic_bridge ( struct  ast_channel  * c0 ,  struct  ast_channel  * c1 , 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-05 23:52:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														 struct  ast_bridge_config  * config ,  struct  ast_frame  * * fo , 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
														 struct  ast_channel  * * rc ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-05-03 02:02:27 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Copy voice back and forth between the two channels. */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * cs [ 3 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_frame  * f ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-11 10:37:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									enum  ast_bridge_result  res  =  AST_BRIDGE_COMPLETE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									format_t  o0nativeformats ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									format_t  o1nativeformats ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  watch_c0_dtmf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  watch_c1_dtmf ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-01 00:10:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									void  * pvt0 ,  * pvt1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-31 16:56:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Indicates whether a frame was queued into a jitterbuffer */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  frame_put_in_jb  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  jb_in_use ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-05 23:52:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  to ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									cs [ 0 ]  =  c0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									cs [ 1 ]  =  c1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-09-01 00:10:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pvt0  =  c0 - > tech_pvt ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pvt1  =  c1 - > tech_pvt ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									o0nativeformats  =  c0 - > nativeformats ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									o1nativeformats  =  c1 - > nativeformats ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									watch_c0_dtmf  =  config - > flags  &  AST_BRIDGE_DTMF_CHANNEL_0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									watch_c1_dtmf  =  config - > flags  &  AST_BRIDGE_DTMF_CHANNEL_1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-31 16:56:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Check the need of a jitterbuffer for each channel */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									jb_in_use  =  ast_jb_do_usecheck ( c0 ,  c1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-06 00:30:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( jb_in_use ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_jb_empty_and_reset ( c0 ,  c1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-31 16:56:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_poll_channel_add ( c0 ,  c1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-01 18:09:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( config - > feature_timer  >  0  & &  ast_tvzero ( config - > nexteventts ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* nexteventts is not set when the bridge is not scheduled to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 		 *  break ,  so  calculate  when  the  bridge  should  possibly  break 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 		 *  if  a  partial  feature  match  timed  out  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										config - > nexteventts  =  ast_tvadd ( ast_tvnow ( ) ,  ast_samp2tv ( config - > feature_timer ,  1000 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:51:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										struct  ast_channel  * who ,  * other ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-09-01 00:10:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ( c0 - > tech_pvt  ! =  pvt0 )  | |  ( c1 - > tech_pvt  ! =  pvt1 )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										    ( o0nativeformats  ! =  c0 - > nativeformats )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										    ( o1nativeformats  ! =  c1 - > nativeformats ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* Check for Masquerade, codec changes, etc */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											res  =  AST_BRIDGE_RETRY ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( config - > nexteventts . tv_sec )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											to  =  ast_tvdiff_ms ( config - > nexteventts ,  ast_tvnow ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-25 09:50:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( to  < =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( config - > timelimit  & &  ! config - > feature_timer  & &  ! ast_test_flag ( config ,  AST_FEATURE_WARNING_ACTIVE ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-15 21:36:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													res  =  AST_BRIDGE_RETRY ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 22:08:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													/* generic bridge ending to play warning */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_set_flag ( config ,  AST_FEATURE_WARNING_ACTIVE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												}  else  if  ( config - > feature_timer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													/* feature timer expired - make sure we do not play warning */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_clear_flag ( config ,  AST_FEATURE_WARNING_ACTIVE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													res  =  AST_BRIDGE_RETRY ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 22:08:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-15 21:36:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													res  =  AST_BRIDGE_COMPLETE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 22:08:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-25 09:50:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-01 18:09:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* If a feature has been started and the bridge is configured to 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 			 *  to  not  break ,  leave  the  channel  bridge  when  the  feature  timer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  time  has  elapsed  so  the  DTMF  will  be  sent  to  the  other  side .  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 			 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ! ast_tvzero ( config - > nexteventts ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												int  diff  =  ast_tvdiff_ms ( config - > nexteventts ,  ast_tvnow ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( diff  < =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													res  =  AST_BRIDGE_RETRY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-25 09:50:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											to  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-01 18:09:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-31 16:56:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* Calculate the appropriate max sleep interval - in general, this is the time,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										   left  to  the  closest  jb  delivery  moment  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( jb_in_use ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											to  =  ast_jb_get_when_to_wakeup ( c0 ,  c1 ,  to ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-05 23:52:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										who  =  ast_waitfor_n ( cs ,  2 ,  & to ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! who )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-31 16:56:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* No frame received within the specified timeout - check if we have to deliver now */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( jb_in_use ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_jb_get_and_deliver ( c0 ,  c1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ( c0 - > _softhangup  |  c1 - > _softhangup )  &  AST_SOFTHANGUP_UNBRIDGE )  { /* Bit operators are intentional. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( c0 - > _softhangup  &  AST_SOFTHANGUP_UNBRIDGE )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 303548 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.6.2
................
  r303548 | russell | 2011-01-24 14:49:53 -0600 (Mon, 24 Jan 2011) | 38 lines
  
  Merged revisions 303546 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r303546 | russell | 2011-01-24 14:32:21 -0600 (Mon, 24 Jan 2011) | 31 lines
    
    Fix channel redirect out of MeetMe() and other issues with channel softhangup.
    
    Mantis issue #18585 reports that a channel redirect out of MeetMe() stopped
    working properly.  This issue includes a patch that resolves the issue by
    removing a call to ast_check_hangup() from app_meetme.c.  I left that in my
    patch, as it doesn't need to be there.  However, the rest of the patch fixes
    this problem with or without the change to app_meetme.
    
    The key difference between what happens before and after this patch is the
    effect of the END_OF_Q control frame.  After END_OF_Q is hit in ast_read(),
    ast_read() will return NULL.  With the ast_check_hangup() removed, app_meetme
    sees this which causes it to exit as intended.  Checking ast_check_hangup()
    caused app_meetme to exit earlier in the process, and the target of the
    redirect saw the condition where ast_read() returned NULL.
    
    Removing ast_check_hangup() works around the issue in app_meetme, but doesn't
    solve the issue if another application did the same thing.  There are also
    other edge cases where if an application finishes at the same time that a
    redirect happens, the target of the redirect will think that the channel hung
    up.  So, I made some changes in pbx.c to resolve it at a deeper level.  There
    are already places that unset the SOFTHANGUP_ASYNCGOTO flag in an attempt to
    abort the hangup process.  My patch extends this to remove the END_OF_Q frame
    from the channel's read queue, making the "abort hangup" more complete.  This
    same technique was used in every place where a softhangup flag was cleared.
    
    (closes issue #18585)
    Reported by: oej
    Tested by: oej, wedhorn, russell
    
    Review: https://reviewboard.asterisk.org/r/1082/
  ........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@303549 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2011-01-24 20:51:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_channel_clear_softhangup ( c0 ,  AST_SOFTHANGUP_UNBRIDGE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( c1 - > _softhangup  &  AST_SOFTHANGUP_UNBRIDGE )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 303548 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.6.2
................
  r303548 | russell | 2011-01-24 14:49:53 -0600 (Mon, 24 Jan 2011) | 38 lines
  
  Merged revisions 303546 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r303546 | russell | 2011-01-24 14:32:21 -0600 (Mon, 24 Jan 2011) | 31 lines
    
    Fix channel redirect out of MeetMe() and other issues with channel softhangup.
    
    Mantis issue #18585 reports that a channel redirect out of MeetMe() stopped
    working properly.  This issue includes a patch that resolves the issue by
    removing a call to ast_check_hangup() from app_meetme.c.  I left that in my
    patch, as it doesn't need to be there.  However, the rest of the patch fixes
    this problem with or without the change to app_meetme.
    
    The key difference between what happens before and after this patch is the
    effect of the END_OF_Q control frame.  After END_OF_Q is hit in ast_read(),
    ast_read() will return NULL.  With the ast_check_hangup() removed, app_meetme
    sees this which causes it to exit as intended.  Checking ast_check_hangup()
    caused app_meetme to exit earlier in the process, and the target of the
    redirect saw the condition where ast_read() returned NULL.
    
    Removing ast_check_hangup() works around the issue in app_meetme, but doesn't
    solve the issue if another application did the same thing.  There are also
    other edge cases where if an application finishes at the same time that a
    redirect happens, the target of the redirect will think that the channel hung
    up.  So, I made some changes in pbx.c to resolve it at a deeper level.  There
    are already places that unset the SOFTHANGUP_ASYNCGOTO flag in an attempt to
    abort the hangup process.  My patch extends this to remove the END_OF_Q frame
    from the channel's read queue, making the "abort hangup" more complete.  This
    same technique was used in every place where a softhangup flag was cleared.
    
    (closes issue #18585)
    Reported by: oej
    Tested by: oej, wedhorn, russell
    
    Review: https://reviewboard.asterisk.org/r/1082/
  ........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@303549 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2011-01-24 20:51:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_channel_clear_softhangup ( c1 ,  AST_SOFTHANGUP_UNBRIDGE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2005-05-15 04:48:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												c0 - > _bridge  =  c1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												c1 - > _bridge  =  c0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										f  =  ast_read ( who ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! f )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* fo  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											* rc  =  who ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_debug ( 1 ,  " Didn't get a frame from channel: %s \n " , who - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:51:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										other  =  ( who  = =  c0 )  ?  c1  :  c0 ;  /* the 'other' channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-31 16:56:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* Try add the frame info the who's bridged channel jitterbuff */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( jb_in_use ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											frame_put_in_jb  =  ! ast_jb_put ( other ,  f ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:51:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ( f - > frametype  = =  AST_FRAME_CONTROL )  & &  ! ( config - > flags  &  AST_BRIDGE_IGNORE_SIGS ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-11 10:37:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											int  bridge_exit  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											switch  ( f - > subclass . integer )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Generic Advice of Charge.
Asterisk Generic AOC Representation
- Generic AOC encode/decode routines.
  (Generic AOC must be encoded to be passed on the wire in the AST_CONTROL_AOC frame)
- AST_CONTROL_AOC frame type to represent generic encoded AOC data
- Manager events for AOC-S, AOC-D, and AOC-E messages
Asterisk App Support
- app_dial AOC-S pass-through support on call setup
- app_queue AOC-S pass-through support on call setup
AOC Unit Tests
- AOC Unit Tests for encode/decode routines
- AOC Unit Test for manager event representation.
SIP AOC Support
- Pass-through of generic AOC-D and AOC-E messages to snom phones via the
  snom AOC specification.
- Creation of chan_sip page3 flags for the addition of the new
  'snom_aoc_enabled' sip.conf option.
IAX AOC Support
- Natively supports AOC pass-through through the use of the new
  AST_CONTROL_AOC frame type
DAHDI AOC Support
- ETSI PRI full AOC Pass-through support
- 'aoc_enable' chan_dahdi.conf option for independently enabling
  pass-through of AOC-S, AOC-D, AOC-E.
- 'aoce_delayhangup' option for retrieving AOC-E on disconnect.
- DAHDI A() dial string option for requesting AOC services.
  example usage:
  ;requests AOC-S, AOC-D, and AOC-E on call setup
  exten=>1111,1,Dial(DAHDI/g1/1112/A(s,d,e))
Review:	https://reviewboard.asterisk.org/r/552/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@267096 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-06-02 18:10:15 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											case  AST_CONTROL_AOC : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_indicate_data ( other ,  f - > subclass . integer ,  f - > data . ptr ,  f - > datalen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											case  AST_CONTROL_REDIRECTING : 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( ast_channel_redirecting_macro ( who ,  other ,  f ,  other  = =  c0 ,  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_indicate_data ( other ,  f - > subclass . integer ,  f - > data . ptr ,  f - > datalen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  AST_CONTROL_CONNECTED_LINE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( ast_channel_connected_line_macro ( who ,  other ,  f ,  other  = =  c0 ,  1 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													ast_indicate_data ( other ,  f - > subclass . integer ,  f - > data . ptr ,  f - > datalen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-10 12:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											case  AST_CONTROL_HOLD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  AST_CONTROL_UNHOLD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  AST_CONTROL_VIDUPDATE : 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											case  AST_CONTROL_SRCUPDATE : 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-12 22:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											case  AST_CONTROL_SRCCHANGE : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-29 13:56:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											case  AST_CONTROL_T38_PARAMETERS : 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_indicate_data ( other ,  f - > subclass . integer ,  f - > data . ptr ,  f - > datalen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-08-06 00:30:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( jb_in_use )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_jb_empty_and_reset ( c0 ,  c1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-10 12:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											default : 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												* fo  =  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												* rc  =  who ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-11 10:37:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												bridge_exit  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_debug ( 1 ,  " Got a FRAME_CONTROL (%d) frame on channel %s \n " ,  f - > subclass . integer ,  who - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-11 10:37:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( bridge_exit ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-10 12:24:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ( f - > frametype  = =  AST_FRAME_VOICE )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										    ( f - > frametype  = =  AST_FRAME_DTMF_BEGIN )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										    ( f - > frametype  = =  AST_FRAME_DTMF )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										    ( f - > frametype  = =  AST_FRAME_VIDEO )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										    ( f - > frametype  = =  AST_FRAME_IMAGE )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										    ( f - > frametype  = =  AST_FRAME_HTML )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-12 17:14:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										    ( f - > frametype  = =  AST_FRAME_MODEM )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										    ( f - > frametype  = =  AST_FRAME_TEXT ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:51:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* monitored dtmf causes exit from bridge */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											int  monitored_source  =  ( who  = =  c0 )  ?  watch_c0_dtmf  :  watch_c1_dtmf ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( monitored_source  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												( f - > frametype  = =  AST_FRAME_DTMF_END  | | 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-31 01:59:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												f - > frametype  = =  AST_FRAME_DTMF_BEGIN ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:51:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												* fo  =  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												* rc  =  who ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_debug ( 1 ,  " Got DTMF %s on channel (%s) \n " ,  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													f - > frametype  = =  AST_FRAME_DTMF_END  ?  " end "  :  " begin " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													who - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 22:08:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:51:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-31 16:56:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* Write immediately frames, not passed through jb */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ! frame_put_in_jb ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_write ( other ,  f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* Check if we have to deliver now */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( jb_in_use ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_jb_get_and_deliver ( c0 ,  c1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 15:51:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* XXX do we want to pass on also frames not matched above ? */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifndef HAVE_EPOLL 
 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* Swap who gets priority */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cs [ 2 ]  =  cs [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cs [ 0 ]  =  cs [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										cs [ 1 ]  =  cs [ 2 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2007-08-08 21:44:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_poll_channel_del ( c0 ,  c1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-09-21 19:27:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Bridge two channels together (early) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_early_bridge ( struct  ast_channel  * c0 ,  struct  ast_channel  * c1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Make sure we can early bridge, if not error out */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! c0 - > tech - > early_bridge  | |  ( c1  & &  ( ! c1 - > tech - > early_bridge  | |  c0 - > tech - > early_bridge  ! =  c1 - > tech - > early_bridge ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  c0 - > tech - > early_bridge ( c0 ,  c1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 15:29:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Send manager event for bridge link and unlink events.
 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-15 17:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 *  \ param  onoff  Link / Unlinked  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  type  1  for  core ,  2  for  native 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  c0  first  channel  in  bridge 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  c1  second  channel  in  bridge 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 15:29:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								*/ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  manager_bridge_event ( int  onoff ,  int  type ,  struct  ast_channel  * c0 ,  struct  ast_channel  * c1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * chans [ 2 ]  =  {  c0 ,  c1  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_manager_event_multichan ( EVENT_FLAG_CALL ,  " Bridge " ,  2 ,  chans , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										" Bridgestate: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" Bridgetype: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" Channel1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" Channel2: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" Uniqueid1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" Uniqueid2: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" CallerID1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" CallerID2: %s \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										onoff  ?  " Link "  :  " Unlink " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										type  = =  1  ?  " core "  :  " native " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										c0 - > name ,  c1 - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										c0 - > uniqueid ,  c1 - > uniqueid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										S_COR ( c0 - > caller . id . number . valid ,  c0 - > caller . id . number . str ,  " " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										S_COR ( c1 - > caller . id . number . valid ,  c1 - > caller . id . number . str ,  " " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 15:29:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 22:14:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  update_bridge_vars ( struct  ast_channel  * c0 ,  struct  ast_channel  * c1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 21:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * c0_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * c1_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 22:14:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									const  char  * c0_pvtid  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * c1_pvtid  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 21:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( c1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									c1_name  =  ast_strdupa ( c1 - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 22:14:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( c1 - > tech - > get_pvt_uniqueid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										c1_pvtid  =  ast_strdupa ( c1 - > tech - > get_pvt_uniqueid ( c1 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 21:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( c1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( c0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_strlen_zero ( pbx_builtin_getvar_helper ( c0 ,  " BRIDGEPEER " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pbx_builtin_setvar_helper ( c0 ,  " BRIDGEPEER " ,  c1_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 22:14:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( c1_pvtid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pbx_builtin_setvar_helper ( c0 ,  " BRIDGEPVTCALLID " ,  c1_pvtid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 21:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									c0_name  =  ast_strdupa ( c0 - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 22:14:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( c0 - > tech - > get_pvt_uniqueid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										c0_pvtid  =  ast_strdupa ( c0 - > tech - > get_pvt_uniqueid ( c0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 21:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( c0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( c1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_strlen_zero ( pbx_builtin_getvar_helper ( c1 ,  " BRIDGEPEER " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pbx_builtin_setvar_helper ( c1 ,  " BRIDGEPEER " ,  c0_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 22:14:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( c0_pvtid )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pbx_builtin_setvar_helper ( c1 ,  " BRIDGEPVTCALLID " ,  c0_pvtid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 21:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( c1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 22:25:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  bridge_play_sounds ( struct  ast_channel  * c0 ,  struct  ast_channel  * c1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * s ,  * sound ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* See if we need to play an audio file to any side of the bridge */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( c0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( s  =  pbx_builtin_getvar_helper ( c0 ,  " BRIDGE_PLAY_SOUND " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sound  =  ast_strdupa ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( c0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										bridge_playfile ( c0 ,  c1 ,  sound ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pbx_builtin_setvar_helper ( c0 ,  " BRIDGE_PLAY_SOUND " ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( c0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( c1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( s  =  pbx_builtin_getvar_helper ( c1 ,  " BRIDGE_PLAY_SOUND " ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										sound  =  ast_strdupa ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( c1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										bridge_playfile ( c1 ,  c0 ,  sound ,  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pbx_builtin_setvar_helper ( c1 ,  " BRIDGE_PLAY_SOUND " ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( c1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Bridge two channels together */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								enum  ast_bridge_result  ast_channel_bridge ( struct  ast_channel  * c0 ,  struct  ast_channel  * c1 , 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													  struct  ast_bridge_config  * config ,  struct  ast_frame  * * fo ,  struct  ast_channel  * * rc ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-31 03:00:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-16 23:02:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * chans [ 2 ]  =  {  c0 ,  c1  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									enum  ast_bridge_result  res  =  AST_BRIDGE_COMPLETE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									format_t  o0nativeformats ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									format_t  o1nativeformats ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-13 18:27:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									long  time_left_ms = 0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  caller_warning  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  callee_warning  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-05-20 16:43:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									* fo  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-10-23 12:19:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( c0 - > _bridge )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " %s is already in a bridge with %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-23 12:19:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											c0 - > name ,  c0 - > _bridge - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-23 12:19:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( c1 - > _bridge )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " %s is already in a bridge with %s \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-23 12:19:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											c1 - > name ,  c1 - > _bridge - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Stop if we're a zombie or need a soft hangup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ast_test_flag ( c0 ,  AST_FLAG_ZOMBIE )  | |  ast_check_hangup_locked ( c0 )  | | 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									    ast_test_flag ( c1 ,  AST_FLAG_ZOMBIE )  | |  ast_check_hangup_locked ( c1 ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-09-12 15:54:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									caller_warning  =  ast_test_flag ( & config - > features_caller ,  AST_FEATURE_PLAY_WARNING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									callee_warning  =  ast_test_flag ( & config - > features_callee ,  AST_FEATURE_PLAY_WARNING ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_tvzero ( config - > start_time ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										config - > start_time  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( config - > start_sound )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( caller_warning )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												bridge_playfile ( c0 ,  c1 ,  config - > start_sound ,  config - > timelimit  /  1000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( callee_warning )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												bridge_playfile ( c1 ,  c0 ,  config - > start_sound ,  config - > timelimit  /  1000 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Keep track of bridge */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-10-23 12:19:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									c0 - > _bridge  =  c1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									c1 - > _bridge  =  c0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-21 10:05:45 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_set_owners_and_peers ( c0 ,  c1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-09-04 01:06:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									o0nativeformats  =  c0 - > nativeformats ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									o1nativeformats  =  c1 - > nativeformats ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-03 00:01:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( config - > feature_timer  & &  ! ast_tvzero ( config - > nexteventts ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										config - > nexteventts  =  ast_tvadd ( config - > feature_start_time ,  ast_samp2tv ( config - > feature_timer ,  1000 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  if  ( config - > timelimit )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										time_left_ms  =  config - > timelimit  -  ast_tvdiff_ms ( ast_tvnow ( ) ,  config - > start_time ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 22:08:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										config - > nexteventts  =  ast_tvadd ( config - > start_time ,  ast_samp2tv ( config - > timelimit ,  1000 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ( caller_warning  | |  callee_warning )  & &  config - > play_warning )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											long  next_warn  =  config - > play_warning ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-13 19:51:52 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( time_left_ms  <  config - > play_warning  & &  config - > warning_freq  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												/* At least one warning was played, which means we are returning after feature */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												long  warns_passed  =  ( config - > play_warning  -  time_left_ms )  /  config - > warning_freq ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												/* It is 'warns_passed * warning_freq' NOT '(warns_passed + 1) * warning_freq',
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													because  nexteventts  will  be  updated  once  again  in  the  ' if  ( ! to ) '  block  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												next_warn  =  config - > play_warning  -  warns_passed  *  config - > warning_freq ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											config - > nexteventts  =  ast_tvsub ( config - > nexteventts ,  ast_samp2tv ( next_warn ,  1000 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										config - > nexteventts . tv_sec  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										config - > nexteventts . tv_usec  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-13 18:27:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! c0 - > tech - > send_digit_begin ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_set_flag ( c1 ,  AST_FLAG_END_DTMF_ONLY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! c1 - > tech - > send_digit_begin ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_set_flag ( c0 ,  AST_FLAG_END_DTMF_ONLY ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 15:29:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									manager_bridge_event ( 1 ,  1 ,  c0 ,  c1 ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-03-05 22:43:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Before we enter in and bridge these two together tell them both the source of audio has changed */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-07 22:59:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_indicate ( c0 ,  AST_CONTROL_SRCUPDATE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_indicate ( c1 ,  AST_CONTROL_SRCUPDATE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-05 22:43:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( /* ever */ ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-05 05:26:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										struct  timeval  now  =  {  0 ,  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-01 23:09:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										int  to ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-13 18:27:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										to  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-01 23:09:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 22:08:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ! ast_tvzero ( config - > nexteventts ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-13 18:27:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											now  =  ast_tvnow ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 22:08:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											to  =  ast_tvdiff_ms ( config - > nexteventts ,  now ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( to  < =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-11-15 21:36:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( ! config - > timelimit )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													res  =  AST_BRIDGE_COMPLETE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												to  =  0 ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												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 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-01 23:09:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( config - > timelimit )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-13 18:27:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											time_left_ms  =  config - > timelimit  -  ast_tvdiff_ms ( now ,  config - > start_time ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( time_left_ms  <  to ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												to  =  time_left_ms ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 14:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( time_left_ms  < =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( caller_warning  & &  config - > end_sound ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													bridge_playfile ( c0 ,  c1 ,  config - > end_sound ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-18 14:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( callee_warning  & &  config - > end_sound ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													bridge_playfile ( c1 ,  c0 ,  config - > end_sound ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-27 16:42:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												* fo  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 21:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-10-13 18:27:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ! to )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 22:08:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( time_left_ms  > =  5000  & &  config - > warning_sound  & &  config - > play_warning  & &  ast_test_flag ( config ,  AST_FEATURE_WARNING_ACTIVE ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-16 16:04:24 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													int  t  =  ( time_left_ms  +  500 )  /  1000 ;  /* round to nearest second */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( caller_warning ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														bridge_playfile ( c0 ,  c1 ,  config - > warning_sound ,  t ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													if  ( callee_warning ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
														bridge_playfile ( c1 ,  c0 ,  config - > warning_sound ,  t ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-13 18:27:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												if  ( config - > warning_freq  & &  ( time_left_ms  >  ( config - > warning_freq  +  5000 ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 22:08:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													config - > nexteventts  =  ast_tvadd ( config - > nexteventts ,  ast_samp2tv ( config - > warning_freq ,  1000 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 22:08:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													config - > nexteventts  =  ast_tvadd ( config - > start_time ,  ast_samp2tv ( config - > timelimit ,  1000 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 22:08:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_clear_flag ( config ,  AST_FEATURE_WARNING_ACTIVE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-26 23:22:34 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-23 21:52:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ( c0 - > _softhangup  |  c1 - > _softhangup )  &  AST_SOFTHANGUP_UNBRIDGE )  { /* Bit operators are intentional. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( c0 - > _softhangup  &  AST_SOFTHANGUP_UNBRIDGE )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 303548 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.6.2
................
  r303548 | russell | 2011-01-24 14:49:53 -0600 (Mon, 24 Jan 2011) | 38 lines
  
  Merged revisions 303546 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r303546 | russell | 2011-01-24 14:32:21 -0600 (Mon, 24 Jan 2011) | 31 lines
    
    Fix channel redirect out of MeetMe() and other issues with channel softhangup.
    
    Mantis issue #18585 reports that a channel redirect out of MeetMe() stopped
    working properly.  This issue includes a patch that resolves the issue by
    removing a call to ast_check_hangup() from app_meetme.c.  I left that in my
    patch, as it doesn't need to be there.  However, the rest of the patch fixes
    this problem with or without the change to app_meetme.
    
    The key difference between what happens before and after this patch is the
    effect of the END_OF_Q control frame.  After END_OF_Q is hit in ast_read(),
    ast_read() will return NULL.  With the ast_check_hangup() removed, app_meetme
    sees this which causes it to exit as intended.  Checking ast_check_hangup()
    caused app_meetme to exit earlier in the process, and the target of the
    redirect saw the condition where ast_read() returned NULL.
    
    Removing ast_check_hangup() works around the issue in app_meetme, but doesn't
    solve the issue if another application did the same thing.  There are also
    other edge cases where if an application finishes at the same time that a
    redirect happens, the target of the redirect will think that the channel hung
    up.  So, I made some changes in pbx.c to resolve it at a deeper level.  There
    are already places that unset the SOFTHANGUP_ASYNCGOTO flag in an attempt to
    abort the hangup process.  My patch extends this to remove the END_OF_Q frame
    from the channel's read queue, making the "abort hangup" more complete.  This
    same technique was used in every place where a softhangup flag was cleared.
    
    (closes issue #18585)
    Reported by: oej
    Tested by: oej, wedhorn, russell
    
    Review: https://reviewboard.asterisk.org/r/1082/
  ........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@303549 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2011-01-24 20:51:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_channel_clear_softhangup ( c0 ,  AST_SOFTHANGUP_UNBRIDGE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( c1 - > _softhangup  &  AST_SOFTHANGUP_UNBRIDGE )  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 303548 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.6.2
................
  r303548 | russell | 2011-01-24 14:49:53 -0600 (Mon, 24 Jan 2011) | 38 lines
  
  Merged revisions 303546 via svnmerge from 
  https://origsvn.digium.com/svn/asterisk/branches/1.4
  
  ........
    r303546 | russell | 2011-01-24 14:32:21 -0600 (Mon, 24 Jan 2011) | 31 lines
    
    Fix channel redirect out of MeetMe() and other issues with channel softhangup.
    
    Mantis issue #18585 reports that a channel redirect out of MeetMe() stopped
    working properly.  This issue includes a patch that resolves the issue by
    removing a call to ast_check_hangup() from app_meetme.c.  I left that in my
    patch, as it doesn't need to be there.  However, the rest of the patch fixes
    this problem with or without the change to app_meetme.
    
    The key difference between what happens before and after this patch is the
    effect of the END_OF_Q control frame.  After END_OF_Q is hit in ast_read(),
    ast_read() will return NULL.  With the ast_check_hangup() removed, app_meetme
    sees this which causes it to exit as intended.  Checking ast_check_hangup()
    caused app_meetme to exit earlier in the process, and the target of the
    redirect saw the condition where ast_read() returned NULL.
    
    Removing ast_check_hangup() works around the issue in app_meetme, but doesn't
    solve the issue if another application did the same thing.  There are also
    other edge cases where if an application finishes at the same time that a
    redirect happens, the target of the redirect will think that the channel hung
    up.  So, I made some changes in pbx.c to resolve it at a deeper level.  There
    are already places that unset the SOFTHANGUP_ASYNCGOTO flag in an attempt to
    abort the hangup process.  My patch extends this to remove the END_OF_Q frame
    from the channel's read queue, making the "abort hangup" more complete.  This
    same technique was used in every place where a softhangup flag was cleared.
    
    (closes issue #18585)
    Reported by: oej
    Tested by: oej, wedhorn, russell
    
    Review: https://reviewboard.asterisk.org/r/1082/
  ........
................
git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@303549 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2011-01-24 20:51:37 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_channel_clear_softhangup ( c1 ,  AST_SOFTHANGUP_UNBRIDGE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-23 21:52:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											c0 - > _bridge  =  c1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											c1 - > _bridge  =  c0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_debug ( 1 ,  " Unbridge signal received. Ending native bridge. \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-23 21:52:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 21:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										/* Stop if we're a zombie or need a soft hangup */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ast_test_flag ( c0 ,  AST_FLAG_ZOMBIE )  | |  ast_check_hangup_locked ( c0 )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										    ast_test_flag ( c1 ,  AST_FLAG_ZOMBIE )  | |  ast_check_hangup_locked ( c1 ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											* fo  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											res  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_debug ( 1 ,  " Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												c0 - > name ,  c1 - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_test_flag ( c0 ,  AST_FLAG_ZOMBIE )  ?  " Yes "  :  " No " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_check_hangup ( c0 )  ?  " Yes "  :  " No " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_test_flag ( c1 ,  AST_FLAG_ZOMBIE )  ?  " Yes "  :  " No " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_check_hangup ( c1 )  ?  " Yes "  :  " No " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 21:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 22:14:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										update_bridge_vars ( c0 ,  c1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-25 15:18:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 22:25:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										bridge_play_sounds ( c0 ,  c1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 21:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( c0 - > tech - > bridge  & & 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-23 21:17:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* if < 1 ms remains use generic bridging for accurate timing */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											( ! config - > timelimit  | |  to  >  1000  | |  to  = =  0 )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										    ( c0 - > tech - > bridge  = =  c1 - > tech - > bridge )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2010-02-18 18:31:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										    ! c0 - > monitor  & &  ! c1 - > monitor  & & 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-23 21:17:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										    ! c0 - > audiohooks  & &  ! c1 - > audiohooks  & & 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-29 16:18:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										    ast_framehook_list_is_empty ( c0 - > framehooks )  & &  ast_framehook_list_is_empty ( c1 - > framehooks )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2007-10-08 15:05:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										    ! c0 - > masq  & &  ! c0 - > masqr  & &  ! c1 - > masq  & &  ! c1 - > masqr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-23 21:17:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											int  timeoutms  =  to  -  1000  >  0  ?  to  -  1000  :  to ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-28 23:01:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* Looks like they share a bridge method and nothing else is in the way */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-23 21:52:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_set_flag ( c0 ,  AST_FLAG_NBRIDGE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_set_flag ( c1 ,  AST_FLAG_NBRIDGE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-03-23 21:17:23 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ( res  =  c0 - > tech - > bridge ( c0 ,  c1 ,  config - > flags ,  fo ,  rc ,  timeoutms ) )  = =  AST_BRIDGE_COMPLETE )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_manager_event_multichan ( EVENT_FLAG_CALL ,  " Unlink " ,  2 ,  chans , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													" Channel1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													" Channel2: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													" Uniqueid1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													" Uniqueid2: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													" CallerID1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													" CallerID2: %s \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													c0 - > name ,  c1 - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													c0 - > uniqueid ,  c1 - > uniqueid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													S_COR ( c0 - > caller . id . number . valid ,  c0 - > caller . id . number . str ,  " <unknown> " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													S_COR ( c1 - > caller . id . number . valid ,  c1 - > caller . id . number . str ,  " <unknown> " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_debug ( 1 ,  " Returning from native bridge, channels: %s, %s \n " ,  c0 - > name ,  c1 - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-03-23 21:52:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_clear_flag ( c0 ,  AST_FLAG_NBRIDGE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_clear_flag ( c1 ,  AST_FLAG_NBRIDGE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( ( c0 - > _softhangup  |  c1 - > _softhangup )  &  AST_SOFTHANGUP_UNBRIDGE )  { /* Bit operators are intentional. */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-23 21:52:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-22 19:36:10 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												c0 - > _bridge  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												c1 - > _bridge  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-03-23 21:52:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_clear_flag ( c0 ,  AST_FLAG_NBRIDGE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_clear_flag ( c1 ,  AST_FLAG_NBRIDGE ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											switch  ( res )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  AST_BRIDGE_RETRY : 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-07 23:50:56 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												if  ( config - > play_warning )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													ast_set_flag ( config ,  AST_FEATURE_WARNING_ACTIVE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												} 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-02 17:20:35 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											default : 
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_verb ( 3 ,  " Native bridging %s and %s ended \n " ,  c0 - > name ,  c1 - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												/* fallthrough */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											case  AST_BRIDGE_FAILED_NOWARN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 21:49:29 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ( ( c0 - > writeformat  ! =  c1 - > readformat )  | |  ( c0 - > readformat  ! =  c1 - > writeformat )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										    ( c0 - > nativeformats  ! =  o0nativeformats )  | |  ( c1 - > nativeformats  ! =  o1nativeformats ) )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										    ! ( c0 - > generator  | |  c1 - > generator ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ast_channel_make_compatible ( c0 ,  c1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Can't make %s and %s compatible \n " ,  c0 - > name ,  c1 - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-12-06 15:29:05 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												manager_bridge_event ( 0 ,  1 ,  c0 ,  c1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												return  AST_BRIDGE_FAILED ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2004-09-04 01:06:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											o0nativeformats  =  c0 - > nativeformats ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											o1nativeformats  =  c1 - > nativeformats ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-09-19 14:40:16 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-10 12:54:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-03-11 22:14:55 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										update_bridge_vars ( c0 ,  c1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-06-10 12:54:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-08 21:00:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										res  =  ast_generic_bridge ( c0 ,  c1 ,  config ,  fo ,  rc ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 22:08:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( res  ! =  AST_BRIDGE_RETRY )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  if  ( config - > feature_timer )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* feature timer expired but has not been updated, sending to ast_bridge_call to do so */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-02-17 22:08:00 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merged revisions 51311 via svnmerge from 
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r51311 | russell | 2007-01-19 11:49:38 -0600 (Fri, 19 Jan 2007) | 23 lines
Merge the changes from the /team/group/vldtmf_fixup branch.
The main bug being addressed here is a problem introduced when two SIP
channels using SIP INFO dtmf have their media directly bridged.  So, when a
DTMF END frame comes into Asterisk from an incoming INFO message, Asterisk
would try to emulate a digit of some length by first sending a DTMF BEGIN
frame and sending a DTMF END later timed off of incoming audio.  However,
since there was no audio coming in, the DTMF_END was never generated.  This
caused DTMF based features to no longer work.
To fix this, the core now knows when a channel doesn't care about DTMF BEGIN
frames (such as a SIP channel sending INFO dtmf).  If this is the case, then
Asterisk will not emulate a digit of some length, and will instead just pass
through the single DTMF END event.
Channel drivers also now get passed the length of the digit to their digit_end
callback.  This improves SIP INFO support even further by enabling us to put
the real digit duration in the INFO message instead of a hard coded 250ms.
Also, for an incoming INFO message, the duration is read from the frame and
passed into the core instead of just getting ignored.
(issue #8597, maybe others...)
........
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@51314 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2007-01-19 18:06:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_clear_flag ( c0 ,  AST_FLAG_END_DTMF_ONLY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_clear_flag ( c1 ,  AST_FLAG_END_DTMF_ONLY ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-03-05 22:43:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Now that we have broken the bridge the source will change yet again */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_indicate ( c0 ,  AST_CONTROL_SRCUPDATE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_indicate ( c1 ,  AST_CONTROL_SRCUPDATE ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-10-23 12:19:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									c0 - > _bridge  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									c1 - > _bridge  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-11-13 20:42:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_manager_event_multichan ( EVENT_FLAG_CALL ,  " Unlink " ,  2 ,  chans , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										" Channel1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" Channel2: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" Uniqueid1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" Uniqueid2: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" CallerID1: %s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" CallerID2: %s \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										c0 - > name ,  c1 - > name , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										c0 - > uniqueid ,  c1 - > uniqueid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										S_COR ( c0 - > caller . id . number . valid ,  c0 - > caller . id . number . str ,  " <unknown> " ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										S_COR ( c1 - > caller . id . number . valid ,  c1 - > caller . id . number . str ,  " <unknown> " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_debug ( 1 ,  " Bridge stops bridging channels %s and %s \n " ,  c0 - > name ,  c1 - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-08-09 01:59:59 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Sets an option on a channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_channel_setoption ( struct  ast_channel  * chan ,  int  option ,  void  * data ,  int  datalen ,  int  block ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-16 22:35:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 23:47:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! chan - > tech - > setoption )  { 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										errno  =  ENOSYS ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-16 22:35:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 23:47:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( block ) 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_ERROR ,  " XXX Blocking not implemented yet XXX \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 23:47:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-06-16 22:35:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									res  =  chan - > tech - > setoption ( chan ,  option ,  data ,  datalen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 23:47:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_queryoption ( struct  ast_channel  * chan ,  int  option ,  void  * data ,  int  * datalen ,  int  block ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-16 22:35:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 23:47:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! chan - > tech - > queryoption )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										errno  =  ENOSYS ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-06-16 22:35:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-05-07 00:43:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2008-02-18 23:47:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( block ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_ERROR ,  " XXX Blocking not implemented yet XXX \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-06-16 22:35:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									res  =  chan - > tech - > queryoption ( chan ,  option ,  data ,  datalen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2001-03-12 03:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2001-12-20 15:21:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  tonepair_def  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  freq1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  freq2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  duration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  vol ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  tonepair_state  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-15 20:25:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  fac1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  fac2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  v1_1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  v2_1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  v3_1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  v1_2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  v2_2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  v3_2 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									format_t  origwfmt ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-15 20:25:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  duration ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  modulate ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_frame  f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  offset [ AST_FRIENDLY_OFFSET ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									short  data [ 4000 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  tonepair_release ( struct  ast_channel  * chan ,  void  * params ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  tonepair_state  * ts  =  params ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-14 20:47:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( chan ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-06 22:17:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_set_write_format ( chan ,  ts - > origwfmt ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_free ( ts ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  * tonepair_alloc ( struct  ast_channel  * chan ,  void  * params ) 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  tonepair_state  * ts ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  tonepair_def  * td  =  params ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-15 01:48:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ( ts  =  ast_calloc ( 1 ,  sizeof ( * ts ) ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ts - > origwfmt  =  chan - > writeformat ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-04-06 22:17:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_set_write_format ( chan ,  AST_FORMAT_SLINEAR ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Unable to set '%s' to signed linear format (write) \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										tonepair_release ( NULL ,  ts ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ts  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-15 20:25:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ts - > fac1  =  2.0  *  cos ( 2.0  *  M_PI  *  ( td - > freq1  /  8000.0 ) )  *  32768.0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ts - > v1_1  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ts - > v2_1  =  sin ( - 4.0  *  M_PI  *  ( td - > freq1  /  8000.0 ) )  *  td - > vol ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ts - > v3_1  =  sin ( - 2.0  *  M_PI  *  ( td - > freq1  /  8000.0 ) )  *  td - > vol ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ts - > v2_1  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ts - > fac2  =  2.0  *  cos ( 2.0  *  M_PI  *  ( td - > freq2  /  8000.0 ) )  *  32768.0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ts - > v2_2  =  sin ( - 4.0  *  M_PI  *  ( td - > freq2  /  8000.0 ) )  *  td - > vol ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ts - > v3_2  =  sin ( - 2.0  *  M_PI  *  ( td - > freq2  /  8000.0 ) )  *  td - > vol ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ts - > duration  =  td - > duration ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-15 20:25:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ts - > modulate  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Let interrupts interrupt :) */ 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-07 20:38:43 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_set_flag ( chan ,  AST_FLAG_WRITE_INT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ts ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  tonepair_generator ( struct  ast_channel  * chan ,  void  * data ,  int  len ,  int  samples ) 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  tonepair_state  * ts  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* we need to prepare a frame with 16 * timelen samples as we're
 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									 *  generating  SLIN  audio 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									len  =  samples  *  2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( len  >  sizeof ( ts - > data )  /  2  -  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " Can't generate that much data! \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									memset ( & ts - > f ,  0 ,  sizeof ( ts - > f ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-08-15 20:25:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								 	for  ( x = 0 ; x < len / 2 ; x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 		ts - > v1_1  =  ts - > v2_1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 		ts - > v2_1  =  ts - > v3_1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 		ts - > v3_1  =  ( ts - > fac1  *  ts - > v2_1  > >  15 )  -  ts - > v1_1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 		
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 		ts - > v1_2  =  ts - > v2_2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 		ts - > v2_2  =  ts - > v3_2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 		ts - > v3_2  =  ( ts - > fac2  *  ts - > v2_2  > >  15 )  -  ts - > v1_2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 		if  ( ts - > modulate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 			int  p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 			p  =  ts - > v3_2  -  32768 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 			if  ( p  <  0 )  p  =  - p ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 			p  =  ( ( p  *  9 )  /  10 )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 			ts - > data [ x ]  =  ( ts - > v3_1  *  p )  > >  15 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 		}  else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 			ts - > data [ x ]  =  ts - > v3_1  +  ts - > v3_2 ;  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 	} 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ts - > f . frametype  =  AST_FRAME_VOICE ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ts - > f . subclass . codec  =  AST_FORMAT_SLINEAR ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ts - > f . datalen  =  len ; 
							 
						 
					
						
							
								
									
										
										
										
											2003-02-05 21:18:09 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ts - > f . samples  =  samples ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ts - > f . offset  =  AST_FRIENDLY_OFFSET ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-22 16:29:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ts - > f . data . ptr  =  ts - > data ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_write ( chan ,  & ts - > f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ts - > pos  + =  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ts - > duration  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ts - > pos  > =  ts - > duration  *  8 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  struct  ast_generator  tonepair  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									alloc :  tonepair_alloc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									release :  tonepair_release , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									generate :  tonepair_generator , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_tonepair_start ( struct  ast_channel  * chan ,  int  freq1 ,  int  freq2 ,  int  duration ,  int  vol ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  tonepair_def  d  =  {  0 ,  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									d . freq1  =  freq1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									d . freq2  =  freq2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									d . duration  =  duration ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									d . vol  =  ( vol  <  1 )  ?  8192  :  vol ;  /* force invalid to 8192 */ 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_activate_generator ( chan ,  & tonepair ,  & d ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_tonepair_stop ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_deactivate_generator ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_tonepair ( struct  ast_channel  * chan ,  int  freq1 ,  int  freq2 ,  int  duration ,  int  vol ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ( res  =  ast_tonepair_start ( chan ,  freq1 ,  freq2 ,  duration ,  vol ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Give us some wiggle room */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									while  ( chan - > generatordata  & &  ast_waitfor ( chan ,  100 )  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										struct  ast_frame  * f  =  ast_read ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2002-06-21 01:40:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( f ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_frfree ( f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2003-03-25 19:30:06 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-11-16 08:18:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								ast_group_t  ast_get_group ( const  char  * s ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-02-27 06:15:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  * piece ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-05-03 17:44:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  * c ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  start = 0 ,  finish = 0 ,  x ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-15 21:51:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_group_t  group  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-12-27 21:41:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_strlen_zero ( s ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-05-03 17:44:30 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									c  =  ast_strdupa ( s ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-02-27 06:15:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
									
										
										
										
											2005-12-24 05:18:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									while  ( ( piece  =  strsep ( & c ,  " , " ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-10 19:20:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( sscanf ( piece ,  " %30d-%30d " ,  & start ,  & finish )  = =  2 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2004-02-27 06:15:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* Range */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-08-10 19:20:57 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										}  else  if  ( sscanf ( piece ,  " %30d " ,  & start ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2004-02-27 06:15:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											/* Just one */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											finish  =  start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_log ( LOG_ERROR ,  " Syntax error parsing group configuration '%s' at '%s'. Ignoring. \n " ,  s ,  piece ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-13 03:31:58 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-02-27 06:15:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										for  ( x  =  start ;  x  < =  finish ;  x + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-15 21:51:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ( x  >  63 )  | |  ( x  <  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Ignoring invalid group %d (maximum group is 63) \n " ,  x ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-02-27 06:15:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											}  else 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												group  | =  ( ( ast_group_t )  1  < <  x ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-02-27 06:15:49 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  group ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 19:55:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-07-19 20:44:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  ( * ast_moh_start_ptr ) ( struct  ast_channel  * ,  const  char  * ,  const  char  * )  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 19:55:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  ( * ast_moh_stop_ptr ) ( struct  ast_channel  * )  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-24 01:40:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  ( * ast_moh_cleanup_ptr ) ( struct  ast_channel  * )  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 19:55:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-07-19 20:44:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_install_music_functions ( int  ( * start_ptr ) ( struct  ast_channel  * ,  const  char  * ,  const  char  * ) , 
							 
						 
					
						
							
								
									
										
										
										
											2006-02-01 23:05:28 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												 void  ( * stop_ptr ) ( struct  ast_channel  * ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												 void  ( * cleanup_ptr ) ( struct  ast_channel  * ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 19:55:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_moh_start_ptr  =  start_ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_moh_stop_ptr  =  stop_ptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-24 01:40:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_moh_cleanup_ptr  =  cleanup_ptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 19:55:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_uninstall_music_functions ( void ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 19:55:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_moh_start_ptr  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_moh_stop_ptr  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-24 01:40:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_moh_cleanup_ptr  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 19:55:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Turn on music on hold on a given channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-19 20:44:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_moh_start ( struct  ast_channel  * chan ,  const  char  * mclass ,  const  char  * interpclass ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 19:55:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-25 22:13:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_moh_start_ptr ) 
							 
						 
					
						
							
								
									
										
										
										
											2006-07-19 20:44:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  ast_moh_start_ptr ( chan ,  mclass ,  interpclass ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-07-26 15:49:18 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_verb ( 3 ,  " Music class %s requested but no musiconhold loaded. \n " ,  mclass  ?  mclass  :  ( interpclass  ?  interpclass  :  " default " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 19:55:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Turn off music on hold on a given channel */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_moh_stop ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 19:55:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-24 05:18:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_moh_stop_ptr ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-09 19:55:01 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_moh_stop_ptr ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-24 01:40:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_moh_cleanup ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-24 01:40:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-24 05:18:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_moh_cleanup_ptr ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_moh_cleanup_ptr ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-24 01:40:07 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  ast_channel_hash_cb ( const  void  * obj ,  const  int  flags ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  struct  ast_channel  * chan  =  obj ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* If the name isn't set, return 0 so that the ao2_find() search will
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  start  in  the  first  bucket .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ast_strlen_zero ( chan - > name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ast_str_case_hash ( chan - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Fix transcode_via_sln option with SIP calls and improve PLC usage.
From reviewboard:
The problem here is a bit complex, so try to bear with me...
It was noticed by a Digium customer that generic PLC (as configured in
codecs.conf) did not appear to actually be having any sort of benefit when
packet loss was introduced on an RTP stream. I reproduced this issue myself
by streaming a file across an RTP stream and dropping approx. 5% of the
RTP packets. I saw no real difference between when PLC was enabled or disabled
when using wireshark to analyze the RTP streams.
After analyzing what was going on, it became clear that one of the problems
faced was that when running my tests, the translation paths were being set
up in such a way that PLC could not possibly work as expected. To illustrate,
if packets are lost on channel A's read stream, then we expect that PLC will
be applied to channel B's write stream. The problem is that generic PLC can
only be done when there is a translation path that moves from some codec to
SLINEAR. When I would run my tests, I found that every single time, read
and write translation paths would be set up on channel A instead of channel
B. There appeared to be no real way to predict which channel the translation
paths would be set up on.
This is where Kevin swooped in to let me know about the transcode_via_sln
option in asterisk.conf. It is supposed to work by placing a read translation
path on both channels from the channel's rawreadformat to SLINEAR. It also
will place a write translation path on both channels from SLINEAR to the
channel's rawwriteformat. Using this option allows one to predictably set up
translation paths on all channels. There are two problems with this, though.
First and foremost, the transcode_via_sln option did not appear to be working
properly when I was placing a SIP call between two endpoints which did not
share any common formats. Second, even if this option were to work, for PLC
to be applied, there had to be a write translation path that would go from
some format to SLINEAR. It would not work properly if the starting format
of translation was SLINEAR.
The one-line change presented in this review request in chan_sip.c fixed the
first issue for me. The problem was that in sip_request_call, the
jointcapability of the outbound channel was being set to the format passed to
sip_request_call. This is nativeformats of the inbound channel. Because of this,
when ast_channel_make_compatible was called by app_dial, both channels already
had compatibly read and write formats. Thus, no translation path was set up at
the time. My change is to set the jointcapability of the sip_pvt created during
sip_request_call to the intersection of the inbound channel's nativeformats and
the configured peer capability that we determined during the earlier call to
create_addr. Doing this got the translation paths set up as expected when using
transcode_via_sln.
The changes presented in channel.c fixed the second issue for me. First and
foremost, when Asterisk is started, we'll read codecs.conf to see the value of
the genericplc option. If this option is set, and ast_write is called for a
frame with no data, then we will attempt to fill in the missing samples for
the frame. The implementation uses a channel datastore for maintaining the
PLC state and for creating a buffer to store PLC samples in. Even when we
receive a frame with data, we'll call plc_rx so that the PLC state will have
knowledge of the previous voice frame, which it can use as a basis for when
it comes time to actually do a PLC fill-in.
So, reviewers, now I ask for your help. First off, there's the one line change
in chan_sip that I have put in. Is it right? By my logic it seems correct, but
I'm sure someone can tell me why it is not going to work. This is probably the
change I'm least concerned about, though. What concerns me much more is the
set of changes in channel.c. First off, am I even doing it right? When I run
tests, I can clearly see that when PLC is activated, I see a significant increase
in RTP traffic where I would expect it to be. However, in my humble opinion, the
audio sounds kind of crappy whenever the PLC fill-in is done. It sounds worse to
me than when no PLC is used at all. I need someone to review the logic I have used
to be sure that I'm not misusing anything. As far as I can see my pointer arithmetic
is correct, and my use of AST_FRIENDLY_OFFSET should be correct as well, but I'm
sure someone can point out somewhere where I've done something incorrectly.
As I was writing this review request up, I decided to give the code a test run under
valgrind, and I find that for some reason, calls to plc_rx are causing some invalid
reads. Apparently I'm reading past the end of a buffer somehow. I'll have to dig around
a bit to see why that is the case. If it's obvious to someone reviewing, speak up!
Finally, I have one other proposal that is not reflected in my code review. Since
without transcode_via_sln set, one cannot predict or control where a translation
path will be up, it seems to me that the current practice of using PLC only when
transcoding to SLINEAR is not useful. I recommend that once it has been determined
that the method used in this code review is correct and works as expected, then
the code in translate.c that invokes PLC should be removed.
Review: https://reviewboard.asterisk.org/r/622/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264452 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-19 21:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_plc_reload ( void ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_variable  * var ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_flags  config_flags  =  {  0  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_config  * cfg  =  ast_config_load ( " codecs.conf " ,  config_flags ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( cfg  = =  CONFIG_STATUS_FILEMISSING  | |  cfg  = =  CONFIG_STATUS_FILEUNCHANGED  | |  cfg  = =  CONFIG_STATUS_FILEINVALID ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( var  =  ast_variable_browse ( cfg ,  " plc " ) ;  var ;  var  =  var - > next )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! strcasecmp ( var - > name ,  " genericplc " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_set2_flag ( & ast_options ,  ast_true ( var - > value ) ,  AST_OPT_FLAG_GENERIC_PLC ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_config_destroy ( cfg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 18:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Implements  the  channels  provider . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  data_channels_provider_handler ( const  struct  ast_data_search  * search , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_data  * root ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel  * c ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 18:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_channel_iterator  * iter  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									struct  ast_data  * data_channel ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 18:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( iter  =  ast_channel_iterator_all_new ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										iter  & &  ( c  =  ast_channel_iterator_next ( iter ) ) ;  ast_channel_unref ( c ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_lock ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										data_channel  =  ast_data_add_node ( root ,  " channel " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! data_channel )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_unlock ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( ast_channel_data_add_structure ( data_channel ,  c ,  1 )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_ERROR ,  " Unable to add channel structure for channel: %s \n " ,  c - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 18:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( c ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! ast_data_search_match ( search ,  data_channel ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_data_remove_node ( root ,  data_channel ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 18:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( iter )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_channel_iterator_destroy ( iter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Implements  the  channeltypes  provider . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  data_channeltypes_provider_handler ( const  struct  ast_data_search  * search , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_data  * data_root ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  chanlist  * cl ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_data  * data_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_RWLIST_RDLOCK ( & backends ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_RWLIST_TRAVERSE ( & backends ,  cl ,  list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										data_type  =  ast_data_add_node ( data_root ,  " type " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! data_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_str ( data_type ,  " name " ,  cl - > tech - > type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_str ( data_type ,  " description " ,  cl - > tech - > description ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " devicestate " ,  cl - > tech - > devicestate  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " indications " ,  cl - > tech - > indicate  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " transfer " ,  cl - > tech - > transfer  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " send_digit_begin " ,  cl - > tech - > send_digit_begin  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " send_digit_end " ,  cl - > tech - > send_digit_end  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " call " ,  cl - > tech - > call  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " hangup " ,  cl - > tech - > hangup  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " answer " ,  cl - > tech - > answer  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " read " ,  cl - > tech - > read  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " write " ,  cl - > tech - > write  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " send_text " ,  cl - > tech - > send_text  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " send_image " ,  cl - > tech - > send_image  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " send_html " ,  cl - > tech - > send_html  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " exception " ,  cl - > tech - > exception  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " bridge " ,  cl - > tech - > bridge  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " early_bridge " ,  cl - > tech - > early_bridge  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " fixup " ,  cl - > tech - > fixup  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " setoption " ,  cl - > tech - > setoption  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " queryoption " ,  cl - > tech - > queryoption  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " write_video " ,  cl - > tech - > write_video  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " write_text " ,  cl - > tech - > write_text  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " bridged_channel " ,  cl - > tech - > bridged_channel  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " func_channel_read " ,  cl - > tech - > func_channel_read  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " func_channel_write " ,  cl - > tech - > func_channel_write  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " get_base_channel " ,  cl - > tech - > get_base_channel  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " set_base_channel " ,  cl - > tech - > set_base_channel  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " get_pvt_uniqueid " ,  cl - > tech - > get_pvt_uniqueid  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_bool ( data_type ,  " cc_callback " ,  cl - > tech - > cc_callback  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_data_add_codecs ( data_type ,  " capabilities " ,  cl - > tech - > capabilities ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! ast_data_search_match ( search ,  data_type ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_data_remove_node ( data_root ,  data_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_RWLIST_UNLOCK ( & backends ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 18:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  / asterisk / core / channels  provider . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  const  struct  ast_data_handler  channels_provider  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. version  =  AST_DATA_HANDLER_VERSION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. get  =  data_channels_provider_handler 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  / asterisk / core / channeltypes  provider . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  const  struct  ast_data_handler  channeltypes_provider  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. version  =  AST_DATA_HANDLER_VERSION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. get  =  data_channeltypes_provider_handler 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 18:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  const  struct  ast_data_entry  channel_providers [ ]  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_DATA_ENTRY ( " /asterisk/core/channels " ,  & channels_provider ) , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-08 14:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_DATA_ENTRY ( " /asterisk/core/channeltypes " ,  & channeltypes_provider ) , 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 18:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2004-12-31 00:04:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channels_init ( void ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Convert the ast_channel data structure over to the astobj2 framework.
There is a lot that could be said about this, but the patch is a big 
improvement for performance, stability, code maintainability, 
and ease of future code development.
The channel list is no longer an unsorted linked list.  The main container 
for channels is an astobj2 hash table.  All of the code related to searching 
for channels or iterating active channels has been rewritten.  Let n be 
the number of active channels.  Iterating the channel list has gone from 
O(n^2) to O(n).  Searching for a channel by name went from O(n) to O(1).  
Searching for a channel by extension is still O(n), but uses a new method 
for doing so, which is more efficient.
The ast_channel object is now a reference counted object.  The benefits 
here are plentiful.  Some benefits directly related to issues in the 
previous code include:
1) When threads other than the channel thread owning a channel wanted 
   access to a channel, it had to hold the lock on it to ensure that it didn't 
   go away.  This is no longer a requirement.  Holding a reference is 
   sufficient.
2) There are places that now require less dealing with channel locks.
3) There are places where channel locks are held for much shorter periods 
   of time.
4) There are places where dealing with more than one channel at a time becomes 
   _MUCH_ easier.  ChanSpy is a great example of this.  Writing code in the 
   future that deals with multiple channels will be much easier.
Some additional information regarding channel locking and reference count 
handling can be found in channel.h, where a new section has been added that 
discusses some of the rules associated with it.
Mark Michelson also assisted with the development of this patch.  He did the 
conversion of ChanSpy and introduced a new API, ast_autochan, which makes it 
much easier to deal with holding on to a channel pointer for an extended period 
of time and having it get automatically updated if the channel gets masqueraded.
Mark was also a huge help in the code review process.
Thanks to David Vossel for his assistance with this branch, as well.  David 
did the conversion of the DAHDIScan application by making it become a wrapper 
for ChanSpy internally.
The changes come from the svn/asterisk/team/russell/ast_channel_ao2 branch.
Review: http://reviewboard.digium.com/r/203/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@190423 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2009-04-24 14:04:26 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									channels  =  ao2_container_alloc ( NUM_CHANNEL_BUCKETS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_channel_hash_cb ,  ast_channel_cmp_cb ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:30:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_cli_register_multiple ( cli_channel ,  ARRAY_LEN ( cli_channel ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-04-22 18:07:02 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_data_register_multiple_core ( channel_providers ,  ARRAY_LEN ( channel_providers ) ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Fix transcode_via_sln option with SIP calls and improve PLC usage.
From reviewboard:
The problem here is a bit complex, so try to bear with me...
It was noticed by a Digium customer that generic PLC (as configured in
codecs.conf) did not appear to actually be having any sort of benefit when
packet loss was introduced on an RTP stream. I reproduced this issue myself
by streaming a file across an RTP stream and dropping approx. 5% of the
RTP packets. I saw no real difference between when PLC was enabled or disabled
when using wireshark to analyze the RTP streams.
After analyzing what was going on, it became clear that one of the problems
faced was that when running my tests, the translation paths were being set
up in such a way that PLC could not possibly work as expected. To illustrate,
if packets are lost on channel A's read stream, then we expect that PLC will
be applied to channel B's write stream. The problem is that generic PLC can
only be done when there is a translation path that moves from some codec to
SLINEAR. When I would run my tests, I found that every single time, read
and write translation paths would be set up on channel A instead of channel
B. There appeared to be no real way to predict which channel the translation
paths would be set up on.
This is where Kevin swooped in to let me know about the transcode_via_sln
option in asterisk.conf. It is supposed to work by placing a read translation
path on both channels from the channel's rawreadformat to SLINEAR. It also
will place a write translation path on both channels from SLINEAR to the
channel's rawwriteformat. Using this option allows one to predictably set up
translation paths on all channels. There are two problems with this, though.
First and foremost, the transcode_via_sln option did not appear to be working
properly when I was placing a SIP call between two endpoints which did not
share any common formats. Second, even if this option were to work, for PLC
to be applied, there had to be a write translation path that would go from
some format to SLINEAR. It would not work properly if the starting format
of translation was SLINEAR.
The one-line change presented in this review request in chan_sip.c fixed the
first issue for me. The problem was that in sip_request_call, the
jointcapability of the outbound channel was being set to the format passed to
sip_request_call. This is nativeformats of the inbound channel. Because of this,
when ast_channel_make_compatible was called by app_dial, both channels already
had compatibly read and write formats. Thus, no translation path was set up at
the time. My change is to set the jointcapability of the sip_pvt created during
sip_request_call to the intersection of the inbound channel's nativeformats and
the configured peer capability that we determined during the earlier call to
create_addr. Doing this got the translation paths set up as expected when using
transcode_via_sln.
The changes presented in channel.c fixed the second issue for me. First and
foremost, when Asterisk is started, we'll read codecs.conf to see the value of
the genericplc option. If this option is set, and ast_write is called for a
frame with no data, then we will attempt to fill in the missing samples for
the frame. The implementation uses a channel datastore for maintaining the
PLC state and for creating a buffer to store PLC samples in. Even when we
receive a frame with data, we'll call plc_rx so that the PLC state will have
knowledge of the previous voice frame, which it can use as a basis for when
it comes time to actually do a PLC fill-in.
So, reviewers, now I ask for your help. First off, there's the one line change
in chan_sip that I have put in. Is it right? By my logic it seems correct, but
I'm sure someone can tell me why it is not going to work. This is probably the
change I'm least concerned about, though. What concerns me much more is the
set of changes in channel.c. First off, am I even doing it right? When I run
tests, I can clearly see that when PLC is activated, I see a significant increase
in RTP traffic where I would expect it to be. However, in my humble opinion, the
audio sounds kind of crappy whenever the PLC fill-in is done. It sounds worse to
me than when no PLC is used at all. I need someone to review the logic I have used
to be sure that I'm not misusing anything. As far as I can see my pointer arithmetic
is correct, and my use of AST_FRIENDLY_OFFSET should be correct as well, but I'm
sure someone can point out somewhere where I've done something incorrectly.
As I was writing this review request up, I decided to give the code a test run under
valgrind, and I find that for some reason, calls to plc_rx are causing some invalid
reads. Apparently I'm reading past the end of a buffer somehow. I'll have to dig around
a bit to see why that is the case. If it's obvious to someone reviewing, speak up!
Finally, I have one other proposal that is not reflected in my code review. Since
without transcode_via_sln set, one cannot predict or control where a translation
path will be up, it seems to me that the current practice of using PLC only when
transcoding to SLINEAR is not useful. I recommend that once it has been determined
that the method used in this code review is correct and works as expected, then
the code in translate.c that invokes PLC should be removed.
Review: https://reviewboard.asterisk.org/r/622/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@264452 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-19 21:29:08 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_plc_reload ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2004-12-31 00:04:41 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-15 21:51:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-31 16:35:48 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \brief Print call group and pickup group ---*/ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								char  * ast_print_group ( char  * buf ,  int  buflen ,  ast_group_t  group ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-15 21:51:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  int  i ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:30:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  first  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-15 21:51:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  num [ 3 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									buf [ 0 ]  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! group ) 	/* Return empty string if no group */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-24 05:18:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  buf ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-15 21:51:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-12-24 05:18:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									for  ( i  =  0 ;  i  < =  63 ;  i + + )  { 	/* Max group is 63 */ 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-12 15:13:39 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( group  &  ( ( ast_group_t )  1  < <  i ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-15 21:51:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									   		if  ( ! first )  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-07 06:54:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												strncat ( buf ,  " ,  " ,  buflen  -  strlen ( buf )  -  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-15 21:51:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											}  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:30:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												first  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-15 21:51:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									  		} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											snprintf ( num ,  sizeof ( num ) ,  " %u " ,  i ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-03-07 06:54:47 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											strncat ( buf ,  num ,  buflen  -  strlen ( buf )  -  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-15 21:51:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2005-12-24 05:18:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  buf ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-01-15 21:51:38 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2005-07-15 23:24:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_set_variables ( struct  ast_channel  * chan ,  struct  ast_variable  * vars ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_variable  * cur ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( cur  =  vars ;  cur ;  cur  =  cur - > next ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pbx_builtin_setvar_helper ( chan ,  cur - > name ,  cur - > value ) ; 	
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2005-10-28 23:01:13 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-01 17:22:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  * silence_generator_alloc ( struct  ast_channel  * chan ,  void  * data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* just store the data pointer in the channel structure */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  silence_generator_release ( struct  ast_channel  * chan ,  void  * data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* nothing to do */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  int  silence_generator_generate ( struct  ast_channel  * chan ,  void  * data ,  int  len ,  int  samples ) 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-01 17:22:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									short  buf [ samples ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_frame  frame  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. frametype  =  AST_FRAME_VOICE , 
							 
						 
					
						
							
								
									
										
										
										
											2009-11-04 14:05:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										. subclass . codec  =  AST_FORMAT_SLINEAR , 
							 
						 
					
						
							
								
									
										
										
										
											2008-05-22 16:29:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										. data . ptr  =  buf , 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										. samples  =  samples , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. datalen  =  sizeof ( buf ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:30:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-19 06:58:20 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									memset ( buf ,  0 ,  sizeof ( buf ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:30:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ast_write ( chan ,  & frame ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:30:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2005-11-01 17:22:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  struct  ast_generator  silence_generator  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. alloc  =  silence_generator_alloc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. release  =  silence_generator_release , 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									. generate  =  silence_generator_generate , 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-01 17:22:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_silence_generator  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  old_write_format ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_silence_generator  * ast_channel_start_silence_generator ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_silence_generator  * state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-02-15 01:48:54 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ( state  =  ast_calloc ( 1 ,  sizeof ( * state ) ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-01 17:22:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									state - > old_write_format  =  chan - > writeformat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ast_set_write_format ( chan ,  AST_FORMAT_SLINEAR )  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_ERROR ,  " Could not set write format to SLINEAR \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_free ( state ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-01 17:22:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_activate_generator ( chan ,  & silence_generator ,  state ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_debug ( 1 ,  " Started silence generator on '%s' \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-01 17:22:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  ast_channel_stop_silence_generator ( struct  ast_channel  * chan ,  struct  ast_silence_generator  * state ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! state ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_deactivate_generator ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-14 19:39:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_debug ( 1 ,  " Stopped silence generator on '%s' \n " ,  chan - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-01 17:22:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ast_set_write_format ( chan ,  state - > old_write_format )  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_ERROR ,  " Could not return write format to its original state \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2007-06-06 21:20:11 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_free ( state ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2005-11-01 17:22:25 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-24 12:48:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \ brief Convert channel reloadreason (ENUM) to text string for manager event */ 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								const  char  * channelreloadreason2txt ( enum  channelreloadreason  reason ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-24 12:48:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									switch  ( reason )  { 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-06 15:40:12 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									case  CHANNEL_MODULE_LOAD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " LOAD (Channel module load) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  CHANNEL_MODULE_RELOAD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " RELOAD (Channel module reload) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  CHANNEL_CLI_RELOAD : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " CLIRELOAD (Channel module reload by CLI command) " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  " MANAGERRELOAD (Channel module reload by manager) " ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-01-24 12:48:44 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-15 08:07:50 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2006-04-19 07:23:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Wrappers  for  various  ast_say_ * ( )  functions  that  call  the  full  version 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  of  the  same  functions . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  The  proper  place  would  be  say . c ,  but  that  file  is  optional  and  one 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  must  be  able  to  build  asterisk  even  without  it  ( using  a  loadable  ' say ' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  implementation  that  only  supplies  the  ' full '  version  of  the  functions . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_say_number ( struct  ast_channel  * chan ,  int  num , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * ints ,  const  char  * language ,  const  char  * options ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:43:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_say_number_full ( chan ,  num ,  ints ,  language ,  options ,  - 1 ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-19 07:23:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_say_enumeration ( struct  ast_channel  * chan ,  int  num , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * ints ,  const  char  * language ,  const  char  * options ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:43:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_say_enumeration_full ( chan ,  num ,  ints ,  language ,  options ,  - 1 ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-19 07:23:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_say_digits ( struct  ast_channel  * chan ,  int  num , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * ints ,  const  char  * lang ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:43:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_say_digits_full ( chan ,  num ,  ints ,  lang ,  - 1 ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-19 07:23:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_say_digit_str ( struct  ast_channel  * chan ,  const  char  * str , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * ints ,  const  char  * lang ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:43:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_say_digit_str_full ( chan ,  str ,  ints ,  lang ,  - 1 ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-19 07:23:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_say_character_str ( struct  ast_channel  * chan ,  const  char  * str , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * ints ,  const  char  * lang ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:43:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_say_character_str_full ( chan ,  str ,  ints ,  lang ,  - 1 ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-19 07:23:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_say_phonetic_str ( struct  ast_channel  * chan ,  const  char  * str , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * ints ,  const  char  * lang ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:43:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  ast_say_phonetic_str_full ( chan ,  str ,  ints ,  lang ,  - 1 ,  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-19 07:23:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_say_digits_full ( struct  ast_channel  * chan ,  int  num , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * ints ,  const  char  * lang ,  int  audiofd ,  int  ctrlfd ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:43:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									char  buf [ 256 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-19 07:23:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2008-01-28 04:43:14 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									snprintf ( buf ,  sizeof ( buf ) ,  " %d " ,  num ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  ast_say_digit_str_full ( chan ,  buf ,  ints ,  lang ,  audiofd ,  ctrlfd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2006-04-19 07:23:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_connected_line_copy_from_caller ( struct  ast_party_connected_line  * dest ,  const  struct  ast_party_caller  * src ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_copy ( & dest - > id ,  & src - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 16:58:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_copy ( & dest - > ani ,  & src - > ani ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									dest - > ani2  =  src - > ani2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_connected_line_copy_to_caller ( struct  ast_party_caller  * dest ,  const  struct  ast_party_connected_line  * src ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_party_id_copy ( & dest - > id ,  & src - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 16:58:03 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_id_copy ( & dest - > ani ,  & src - > ani ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									dest - > ani2  =  src - > ani2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channel_set_connected_line ( struct  ast_channel  * chan ,  const  struct  ast_party_connected_line  * connected ,  const  struct  ast_set_party_connected_line  * update ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( & chan - > connected  = =  connected )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't set to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_connected_line_set ( & chan - > connected ,  connected ,  update ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*! \note Should follow struct ast_party_name */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_party_name_ies  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief Subscriber name ie */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  str ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief Character set ie. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  char_set ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief presentation-indicator ie */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief valid/present ie */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  valid ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ since  1.8 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Build  a  party  name  information  data  frame  component . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  data  Buffer  to  fill  with  the  frame  data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  datalen  Size  of  the  buffer  to  fill 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  name  Party  name  information 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  label  Name  of  particular  party  name 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  ies  Data  frame  ie  values  for  the  party  name  components 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ retval  - 1  if  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ retval  Amount  of  data  buffer  used 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  party_name_build_data ( unsigned  char  * data ,  size_t  datalen ,  const  struct  ast_party_name  * name ,  const  char  * label ,  const  struct  ast_party_name_ies  * ies ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  pos  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  The  size  of  integer  values  must  be  fixed  in  case  the  frame  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  shipped  to  another  machine . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( name - > str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										length  =  strlen ( name - > str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  length )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " No space left for %s name \n " ,  label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										data [ pos + + ]  =  ies - > str ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										data [ pos + + ]  =  length ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										memcpy ( data  +  pos ,  name - > str ,  length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pos  + =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No space left for %s name char set \n " ,  label ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  ies - > char_set ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  name - > char_set ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No space left for %s name presentation \n " ,  label ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  ies - > presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  name - > presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No space left for %s name valid \n " ,  label ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  ies - > valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  name - > valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \note Should follow struct ast_party_number */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_party_number_ies  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief Subscriber phone number ie */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  str ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief Type-Of-Number and Numbering-Plan ie */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  plan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief presentation-indicator ie */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief valid/present ie */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ since  1.8 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Build  a  party  number  information  data  frame  component . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  data  Buffer  to  fill  with  the  frame  data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  datalen  Size  of  the  buffer  to  fill 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  number  Party  number  information 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  label  Name  of  particular  party  number 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  ies  Data  frame  ie  values  for  the  party  number  components 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ retval  - 1  if  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ retval  Amount  of  data  buffer  used 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  party_number_build_data ( unsigned  char  * data ,  size_t  datalen ,  const  struct  ast_party_number  * number ,  const  char  * label ,  const  struct  ast_party_number_ies  * ies ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  pos  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  The  size  of  integer  values  must  be  fixed  in  case  the  frame  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  shipped  to  another  machine . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( number - > str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										length  =  strlen ( number - > str ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  length )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " No space left for %s number \n " ,  label ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										data [ pos + + ]  =  ies - > str ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										data [ pos + + ]  =  length ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										memcpy ( data  +  pos ,  number - > str ,  length ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pos  + =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No space left for %s numbering plan \n " ,  label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  ies - > plan ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  number - > plan ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No space left for %s number presentation \n " ,  label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  ies - > presentation ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  number - > presentation ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No space left for %s number valid \n " ,  label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  ies - > valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  number - > valid ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \note Should follow struct ast_party_subaddress */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_party_subaddress_ies  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief subaddress ie. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  str ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief subaddress type ie */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief odd/even indicator ie */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  odd_even_indicator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief valid/present ie */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ since  1.8 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Build  a  party  subaddress  information  data  frame  component . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  data  Buffer  to  fill  with  the  frame  data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  datalen  Size  of  the  buffer  to  fill 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  subaddress  Party  subaddress  information 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  label  Name  of  particular  party  subaddress 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  ies  Data  frame  ie  values  for  the  party  subaddress  components 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ retval  - 1  if  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ retval  Amount  of  data  buffer  used 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  party_subaddress_build_data ( unsigned  char  * data ,  size_t  datalen ,  const  struct  ast_party_subaddress  * subaddress ,  const  char  * label ,  const  struct  ast_party_subaddress_ies  * ies ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  pos  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  The  size  of  integer  values  must  be  fixed  in  case  the  frame  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  shipped  to  another  machine . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( subaddress - > str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										length  =  strlen ( subaddress - > str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  length )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " No space left for %s subaddress \n " ,  label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										data [ pos + + ]  =  ies - > str ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										data [ pos + + ]  =  length ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										memcpy ( data  +  pos ,  subaddress - > str ,  length ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										pos  + =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No space left for %s type of subaddress \n " ,  label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  ies - > type ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  subaddress - > type ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											" No space left for %s subaddress odd-even indicator \n " ,  label ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  ies - > odd_even_indicator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  subaddress - > odd_even_indicator ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No space left for %s subaddress valid \n " ,  label ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  ies - > valid ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  subaddress - > valid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*! \note Should follow struct ast_party_id */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_party_id_ies  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief Subscriber name ies */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_party_name_ies  name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief Subscriber phone number ies */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_party_number_ies  number ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief Subscriber subaddress ies. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_party_subaddress_ies  subaddress ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief User party id tag ie. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  tag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*! \brief Combined name and number presentation ie. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  combined_presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ internal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ since  1.8 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Build  a  party  id  information  data  frame  component . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  data  Buffer  to  fill  with  the  frame  data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  datalen  Size  of  the  buffer  to  fill 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  id  Party  id  information 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  label  Name  of  particular  party  id 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  ies  Data  frame  ie  values  for  the  party  id  components 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ param  update  What  id  information  to  build .   NULL  if  all . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ retval  - 1  if  error 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ retval  Amount  of  data  buffer  used 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  int  party_id_build_data ( unsigned  char  * data ,  size_t  datalen , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  struct  ast_party_id  * id ,  const  char  * label ,  const  struct  ast_party_id_ies  * ies , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  struct  ast_set_party_id  * update ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  pos  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  The  size  of  integer  values  must  be  fixed  in  case  the  frame  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  shipped  to  another  machine . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! update  | |  update - > name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  party_name_build_data ( data  +  pos ,  datalen  -  pos ,  & id - > name ,  label , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											& ies - > name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pos  + =  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! update  | |  update - > number )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  party_number_build_data ( data  +  pos ,  datalen  -  pos ,  & id - > number ,  label , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											& ies - > number ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pos  + =  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! update  | |  update - > subaddress )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										res  =  party_subaddress_build_data ( data  +  pos ,  datalen  -  pos ,  & id - > subaddress , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											label ,  & ies - > subaddress ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pos  + =  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* *************** Party id user tag **************************** */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( id - > tag )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										length  =  strlen ( id - > tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  length )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " No space left for %s tag \n " ,  label ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										data [ pos + + ]  =  ies - > tag ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										data [ pos + + ]  =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										memcpy ( data  +  pos ,  id - > tag ,  length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										pos  + =  length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* *************** Party id combined presentation *************** */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! update  | |  update - > number )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										int  presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! update  | |  update - > name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											presentation  =  ast_party_id_presentation ( id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										}  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  We  must  compromise  because  not  all  the  information  is  available 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  to  determine  a  combined  presentation  value . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 *  We  will  only  send  the  number  presentation  instead . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											presentation  =  id - > number . presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " No space left for %s combined presentation \n " ,  label ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										data [ pos + + ]  =  ies - > combined_presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										data [ pos + + ]  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										data [ pos + + ]  =  presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Element  identifiers  for  connected  line  indication  frame  data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ note  Only  add  to  the  end  of  this  enum . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								enum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_NUMBER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_NAME , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_NUMBER_PLAN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_ID_PRESENTATION , /* Combined number and name presentation. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_SOURCE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_SUBADDRESS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_SUBADDRESS_TYPE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_SUBADDRESS_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_TAG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_VERSION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_NAME_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_NAME_CHAR_SET , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_NAME_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_NUMBER_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_CONNECTED_LINE_NUMBER_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_connected_line_build_data ( unsigned  char  * data ,  size_t  datalen ,  const  struct  ast_party_connected_line  * connected ,  const  struct  ast_set_party_connected_line  * update ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int32_t  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  pos  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									static  const  struct  ast_party_id_ies  ies  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name . str  =  AST_CONNECTED_LINE_NAME , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name . char_set  =  AST_CONNECTED_LINE_NAME_CHAR_SET , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name . presentation  =  AST_CONNECTED_LINE_NAME_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name . valid  =  AST_CONNECTED_LINE_NAME_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. number . str  =  AST_CONNECTED_LINE_NUMBER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. number . plan  =  AST_CONNECTED_LINE_NUMBER_PLAN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. number . presentation  =  AST_CONNECTED_LINE_NUMBER_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. number . valid  =  AST_CONNECTED_LINE_NUMBER_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. subaddress . str  =  AST_CONNECTED_LINE_SUBADDRESS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. subaddress . type  =  AST_CONNECTED_LINE_SUBADDRESS_TYPE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. subaddress . odd_even_indicator  =  AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. subaddress . valid  =  AST_CONNECTED_LINE_SUBADDRESS_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. tag  =  AST_CONNECTED_LINE_TAG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. combined_presentation  =  AST_CONNECTED_LINE_ID_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  The  size  of  integer  values  must  be  fixed  in  case  the  frame  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 *  shipped  to  another  machine . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Connected line frame version */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No space left for connected line frame version \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  AST_CONNECTED_LINE_VERSION ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  2 ; /* Version 1 did not have a version ie */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									res  =  party_id_build_data ( data  +  pos ,  datalen  -  pos ,  & connected - > id , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" connected line " ,  & ies ,  update  ?  & update - > id  :  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pos  + =  res ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Connected line source */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  sizeof ( value ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No space left for connected line source \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  AST_CONNECTED_LINE_SOURCE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  sizeof ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									value  =  htonl ( connected - > source ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									memcpy ( data  +  pos ,  & value ,  sizeof ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pos  + =  sizeof ( value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_connected_line_parse_data ( const  unsigned  char  * data ,  size_t  datalen ,  struct  ast_party_connected_line  * connected ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  ie_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  ie_id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int32_t  value ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  frame_version  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  combined_presentation  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  got_combined_presentation  =  0 ; /* TRUE if got a combined name and number presentation value. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( pos  =  0 ;  pos  <  datalen ;  pos  + =  ie_len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( datalen  <  pos  +  sizeof ( ie_id )  +  sizeof ( ie_len ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Invalid connected line update \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ie_id  =  data [ pos + + ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ie_len  =  data [ pos + + ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( datalen  <  pos  +  ie_len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Invalid connected line update \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  ( ie_id )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Connected line party frame version */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_VERSION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid connected line frame version (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											frame_version  =  data [ pos ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Connected line party id name */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_NAME : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_free ( connected - > id . name . str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											connected - > id . name . str  =  ast_malloc ( ie_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( connected - > id . name . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												memcpy ( connected - > id . name . str ,  data  +  pos ,  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												connected - > id . name . str [ ie_len ]  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_NAME_CHAR_SET : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid connected line name char set (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											connected - > id . name . char_set  =  data [ pos ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_NAME_PRESENTATION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid connected line name presentation (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											connected - > id . name . presentation  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_NAME_VALID : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid connected line name valid (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											connected - > id . name . valid  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Connected line party id number */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_NUMBER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_free ( connected - > id . number . str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											connected - > id . number . str  =  ast_malloc ( ie_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( connected - > id . number . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												memcpy ( connected - > id . number . str ,  data  +  pos ,  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												connected - > id . number . str [ ie_len ]  =  0 ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_NUMBER_PLAN : 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid connected line numbering plan (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											connected - > id . number . plan  =  data [ pos ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_NUMBER_PRESENTATION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid connected line number presentation (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											connected - > id . number . presentation  =  data [ pos ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_NUMBER_VALID : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid connected line number valid (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											connected - > id . number . valid  =  data [ pos ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Connected line party id combined presentation */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_ID_PRESENTATION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid connected line combined presentation (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											combined_presentation  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											got_combined_presentation  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Connected line party id subaddress */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_SUBADDRESS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_free ( connected - > id . subaddress . str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											connected - > id . subaddress . str  =  ast_malloc ( ie_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( connected - > id . subaddress . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												memcpy ( connected - > id . subaddress . str ,  data  +  pos ,  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												connected - > id . subaddress . str [ ie_len ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_SUBADDRESS_TYPE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid connected line type of subaddress (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											connected - > id . subaddress . type  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													" Invalid connected line subaddress odd-even indicator (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											connected - > id . subaddress . odd_even_indicator  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_SUBADDRESS_VALID : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid connected line subaddress valid (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											connected - > id . subaddress . valid  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Connected line party tag */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_TAG : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_free ( connected - > id . tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											connected - > id . tag  =  ast_malloc ( ie_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( connected - > id . tag )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												memcpy ( connected - > id . tag ,  data  +  pos ,  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												connected - > id . tag [ ie_len ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Connected line party source */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_CONNECTED_LINE_SOURCE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  sizeof ( value ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid connected line source (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											memcpy ( & value ,  data  +  pos ,  sizeof ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											connected - > source  =  ntohl ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Connected line party unknown element */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_log ( LOG_DEBUG ,  " Unknown connected line element: %u (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												( unsigned )  ie_id ,  ( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									switch  ( frame_version )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  The  other  end  is  an  earlier  version  that  we  need  to  adjust 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  for  compatibility . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										connected - > id . name . valid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										connected - > id . name . char_set  =  AST_PARTY_CHAR_SET_ISO8859_1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										connected - > id . number . valid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( got_combined_presentation )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											connected - > id . name . presentation  =  combined_presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											connected - > id . number . presentation  =  combined_presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* The other end is at the same level as we are. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  The  other  end  is  newer  than  we  are . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  We  need  to  assume  that  they  are  compatible  with  us . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_DEBUG ,  " Connected line frame has newer version: %u \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											( unsigned )  frame_version ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channel_update_connected_line ( struct  ast_channel  * chan ,  const  struct  ast_party_connected_line  * connected ,  const  struct  ast_set_party_connected_line  * update ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-21 19:02:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									unsigned  char  data [ 1024 ] ; 	/* This should be large enough */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									size_t  datalen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									datalen  =  ast_connected_line_build_data ( data ,  sizeof ( data ) ,  connected ,  update ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( datalen  = =  ( size_t )  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-09-21 19:02:40 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_indicate_data ( chan ,  AST_CONTROL_CONNECTED_LINE ,  data ,  datalen ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channel_queue_connected_line_update ( struct  ast_channel  * chan ,  const  struct  ast_party_connected_line  * connected ,  const  struct  ast_set_party_connected_line  * update ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  data [ 1024 ] ; 	/* This should be large enough */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  datalen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									datalen  =  ast_connected_line_build_data ( data ,  sizeof ( data ) ,  connected ,  update ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( datalen  = =  ( size_t )  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_queue_control_data ( chan ,  AST_CONTROL_CONNECTED_LINE ,  data ,  datalen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channel_set_redirecting ( struct  ast_channel  * chan ,  const  struct  ast_party_redirecting  * redirecting ,  const  struct  ast_set_party_redirecting  * update ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( & chan - > redirecting  = =  redirecting )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* Don't set to self */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_lock ( chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_party_redirecting_set ( & chan - > redirecting ,  redirecting ,  update ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ brief  Element  identifiers  for  redirecting  indication  frame  data 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  \ note  Only  add  to  the  end  of  this  enum . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								enum  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_NUMBER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_NAME , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_NUMBER_PLAN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_ID_PRESENTATION , 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_NUMBER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_NAME , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_NUMBER_PLAN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_ID_PRESENTATION , 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_REASON , 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_COUNT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_SUBADDRESS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_SUBADDRESS_TYPE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_SUBADDRESS_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_SUBADDRESS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_SUBADDRESS_TYPE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN , 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_SUBADDRESS_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_TAG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_TAG , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_VERSION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_NAME_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_NAME_CHAR_SET , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_NAME_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_NUMBER_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_FROM_NUMBER_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_NAME_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_NAME_CHAR_SET , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_NAME_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_NUMBER_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									AST_REDIRECTING_TO_NUMBER_PRESENTATION , 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_redirecting_build_data ( unsigned  char  * data ,  size_t  datalen ,  const  struct  ast_party_redirecting  * redirecting ,  const  struct  ast_set_party_redirecting  * update ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int32_t  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  pos  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									static  const  struct  ast_party_id_ies  from_ies  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name . str  =  AST_REDIRECTING_FROM_NAME , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name . char_set  =  AST_REDIRECTING_FROM_NAME_CHAR_SET , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name . presentation  =  AST_REDIRECTING_FROM_NAME_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name . valid  =  AST_REDIRECTING_FROM_NAME_VALID , 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										. number . str  =  AST_REDIRECTING_FROM_NUMBER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. number . plan  =  AST_REDIRECTING_FROM_NUMBER_PLAN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. number . presentation  =  AST_REDIRECTING_FROM_NUMBER_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. number . valid  =  AST_REDIRECTING_FROM_NUMBER_VALID , 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										. subaddress . str  =  AST_REDIRECTING_FROM_SUBADDRESS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. subaddress . type  =  AST_REDIRECTING_FROM_SUBADDRESS_TYPE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. subaddress . odd_even_indicator  =  AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. subaddress . valid  =  AST_REDIRECTING_FROM_SUBADDRESS_VALID , 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										. tag  =  AST_REDIRECTING_FROM_TAG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. combined_presentation  =  AST_REDIRECTING_FROM_ID_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									static  const  struct  ast_party_id_ies  to_ies  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name . str  =  AST_REDIRECTING_TO_NAME , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name . char_set  =  AST_REDIRECTING_TO_NAME_CHAR_SET , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name . presentation  =  AST_REDIRECTING_TO_NAME_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. name . valid  =  AST_REDIRECTING_TO_NAME_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. number . str  =  AST_REDIRECTING_TO_NUMBER , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. number . plan  =  AST_REDIRECTING_TO_NUMBER_PLAN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. number . presentation  =  AST_REDIRECTING_TO_NUMBER_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. number . valid  =  AST_REDIRECTING_TO_NUMBER_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. subaddress . str  =  AST_REDIRECTING_TO_SUBADDRESS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. subaddress . type  =  AST_REDIRECTING_TO_SUBADDRESS_TYPE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. subaddress . odd_even_indicator  =  AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. subaddress . valid  =  AST_REDIRECTING_TO_SUBADDRESS_VALID , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. tag  =  AST_REDIRECTING_TO_TAG , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										. combined_presentation  =  AST_REDIRECTING_TO_ID_PRESENTATION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Redirecting frame version */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No space left for redirecting frame version \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  AST_REDIRECTING_VERSION ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  2 ; /* Version 1 did not have a version ie */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									res  =  party_id_build_data ( data  +  pos ,  datalen  -  pos ,  & redirecting - > from , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" redirecting-from " ,  & from_ies ,  update  ?  & update - > from  :  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pos  + =  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									res  =  party_id_build_data ( data  +  pos ,  datalen  -  pos ,  & redirecting - > to , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										" redirecting-to " ,  & to_ies ,  update  ?  & update - > to  :  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( res  <  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									pos  + =  res ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									/* Redirecting reason */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  sizeof ( value ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No space left for redirecting reason \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  AST_REDIRECTING_REASON ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  sizeof ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									value  =  htonl ( redirecting - > reason ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									memcpy ( data  +  pos ,  & value ,  sizeof ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pos  + =  sizeof ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Redirecting count */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( datalen  <  pos  +  ( sizeof ( data [ 0 ] )  *  2 )  +  sizeof ( value ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_WARNING ,  " No space left for redirecting count \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  AST_REDIRECTING_COUNT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									data [ pos + + ]  =  sizeof ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									value  =  htonl ( redirecting - > count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									memcpy ( data  +  pos ,  & value ,  sizeof ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									pos  + =  sizeof ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_redirecting_parse_data ( const  unsigned  char  * data ,  size_t  datalen ,  struct  ast_party_redirecting  * redirecting ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  pos ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  ie_len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  ie_id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int32_t  value ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									int  frame_version  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  from_combined_presentation  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  got_from_combined_presentation  =  0 ; /* TRUE if got a combined name and number presentation value. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  to_combined_presentation  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  got_to_combined_presentation  =  0 ; /* TRUE if got a combined name and number presentation value. */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									for  ( pos  =  0 ;  pos  <  datalen ;  pos  + =  ie_len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( datalen  <  pos  +  sizeof ( ie_id )  +  sizeof ( ie_len ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Invalid redirecting update \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ie_id  =  data [ pos + + ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ie_len  =  data [ pos + + ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( datalen  <  pos  +  ie_len )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_log ( LOG_WARNING ,  " Invalid redirecting update \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										switch  ( ie_id )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Redirecting frame version */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_VERSION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting frame version (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											frame_version  =  data [ pos ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Redirecting-from party id name */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_NAME : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_free ( redirecting - > from . name . str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > from . name . str  =  ast_malloc ( ie_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( redirecting - > from . name . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												memcpy ( redirecting - > from . name . str ,  data  +  pos ,  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												redirecting - > from . name . str [ ie_len ]  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_NAME_CHAR_SET : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-from name char set (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											redirecting - > from . name . char_set  =  data [ pos ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_NAME_PRESENTATION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-from name presentation (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											redirecting - > from . name . presentation  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_NAME_VALID : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-from name valid (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > from . name . valid  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Redirecting-from party id number */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_NUMBER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_free ( redirecting - > from . number . str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > from . number . str  =  ast_malloc ( ie_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( redirecting - > from . number . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												memcpy ( redirecting - > from . number . str ,  data  +  pos ,  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												redirecting - > from . number . str [ ie_len ]  =  0 ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_NUMBER_PLAN : 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-from numbering plan (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											redirecting - > from . number . plan  =  data [ pos ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_NUMBER_PRESENTATION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-from number presentation (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											redirecting - > from . number . presentation  =  data [ pos ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_NUMBER_VALID : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-from number valid (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											redirecting - > from . number . valid  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Redirecting-from party id combined presentation */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_ID_PRESENTATION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-from combined presentation (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											from_combined_presentation  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											got_from_combined_presentation  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Redirecting-from party id subaddress */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_SUBADDRESS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_free ( redirecting - > from . subaddress . str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											redirecting - > from . subaddress . str  =  ast_malloc ( ie_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( redirecting - > from . subaddress . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												memcpy ( redirecting - > from . subaddress . str ,  data  +  pos ,  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												redirecting - > from . subaddress . str [ ie_len ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_SUBADDRESS_TYPE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-from type of subaddress (%u) \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > from . subaddress . type  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													" Invalid redirecting-from subaddress odd-even indicator (%u) \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > from . subaddress . odd_even_indicator  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_SUBADDRESS_VALID : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-from subaddress valid (%u) \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > from . subaddress . valid  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Redirecting-from party id tag */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_FROM_TAG : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_free ( redirecting - > from . tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > from . tag  =  ast_malloc ( ie_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( redirecting - > from . tag )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												memcpy ( redirecting - > from . tag ,  data  +  pos ,  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												redirecting - > from . tag [ ie_len ]  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Redirecting-to party id name */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_NAME : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_free ( redirecting - > to . name . str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > to . name . str  =  ast_malloc ( ie_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( redirecting - > to . name . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												memcpy ( redirecting - > to . name . str ,  data  +  pos ,  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												redirecting - > to . name . str [ ie_len ]  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_NAME_CHAR_SET : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-to name char set (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											redirecting - > to . name . char_set  =  data [ pos ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_NAME_PRESENTATION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-to name presentation (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											redirecting - > to . name . presentation  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_NAME_VALID : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-to name valid (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											redirecting - > to . name . valid  =  data [ pos ] ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Redirecting-to party id number */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_NUMBER : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_free ( redirecting - > to . number . str ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > to . number . str  =  ast_malloc ( ie_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( redirecting - > to . number . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												memcpy ( redirecting - > to . number . str ,  data  +  pos ,  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												redirecting - > to . number . str [ ie_len ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_NUMBER_PLAN : 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-to numbering plan (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											redirecting - > to . number . plan  =  data [ pos ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_NUMBER_PRESENTATION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-to number presentation (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											redirecting - > to . number . presentation  =  data [ pos ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_NUMBER_VALID : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-to number valid (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > to . number . valid  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Redirecting-to party id combined presentation */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_ID_PRESENTATION : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-to combined presentation (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											to_combined_presentation  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											got_to_combined_presentation  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Redirecting-to party id subaddress */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_SUBADDRESS : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_free ( redirecting - > to . subaddress . str ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											redirecting - > to . subaddress . str  =  ast_malloc ( ie_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( redirecting - > to . subaddress . str )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												memcpy ( redirecting - > to . subaddress . str ,  data  +  pos ,  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												redirecting - > to . subaddress . str [ ie_len ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_SUBADDRESS_TYPE : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-to type of subaddress (%u) \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > to . subaddress . type  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING , 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													" Invalid redirecting-to subaddress odd-even indicator (%u) \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > to . subaddress . odd_even_indicator  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_SUBADDRESS_VALID : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting-to subaddress valid (%u) \n " , 
							 
						 
					
						
							
								
									
										
										
										
											2009-10-22 16:33:22 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > to . subaddress . valid  =  data [ pos ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Redirecting-to party id tag */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_TO_TAG : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											ast_free ( redirecting - > to . tag ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > to . tag  =  ast_malloc ( ie_len  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( redirecting - > to . tag )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												memcpy ( redirecting - > to . tag ,  data  +  pos ,  ie_len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												redirecting - > to . tag [ ie_len ]  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Redirecting reason */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_REASON : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  sizeof ( value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting reason (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											memcpy ( & value ,  data  +  pos ,  sizeof ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > reason  =  ntohl ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Redirecting count */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										case  AST_REDIRECTING_COUNT : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											if  ( ie_len  ! =  sizeof ( value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												ast_log ( LOG_WARNING ,  " Invalid redirecting count (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
													( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											memcpy ( & value ,  data  +  pos ,  sizeof ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > count  =  ntohl ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Redirecting unknown element */ 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										default : 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											ast_log ( LOG_DEBUG ,  " Unknown redirecting element: %u (%u) \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												( unsigned )  ie_id ,  ( unsigned )  ie_len ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									switch  ( frame_version )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  The  other  end  is  an  earlier  version  that  we  need  to  adjust 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  for  compatibility . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										redirecting - > from . name . valid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										redirecting - > from . name . char_set  =  AST_PARTY_CHAR_SET_ISO8859_1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										redirecting - > from . number . valid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( got_from_combined_presentation )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > from . name . presentation  =  from_combined_presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > from . number . presentation  =  from_combined_presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										redirecting - > to . name . valid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										redirecting - > to . name . char_set  =  AST_PARTY_CHAR_SET_ISO8859_1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										redirecting - > to . number . valid  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( got_to_combined_presentation )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > to . name . presentation  =  to_combined_presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											redirecting - > to . number . presentation  =  to_combined_presentation ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* The other end is at the same level as we are. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  The  other  end  is  newer  than  we  are . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  We  need  to  assume  that  they  are  compatible  with  us . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_log ( LOG_DEBUG ,  " Redirecting frame has newer version: %u \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											( unsigned )  frame_version ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channel_update_redirecting ( struct  ast_channel  * chan ,  const  struct  ast_party_redirecting  * redirecting ,  const  struct  ast_set_party_redirecting  * update ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  data [ 1024 ] ; 	/* This should be large enough */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  datalen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									datalen  =  ast_redirecting_build_data ( data ,  sizeof ( data ) ,  redirecting ,  update ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( datalen  = =  ( size_t )  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_indicate_data ( chan ,  AST_CONTROL_REDIRECTING ,  data ,  datalen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  ast_channel_queue_redirecting_update ( struct  ast_channel  * chan ,  const  struct  ast_party_redirecting  * redirecting ,  const  struct  ast_set_party_redirecting  * update ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									unsigned  char  data [ 1024 ] ; 	/* This should be large enough */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									size_t  datalen ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									datalen  =  ast_redirecting_build_data ( data ,  sizeof ( data ) ,  redirecting ,  update ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-04-03 22:41:46 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( datalen  = =  ( size_t )  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_queue_control_data ( chan ,  AST_CONTROL_REDIRECTING ,  data ,  datalen ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								int  ast_channel_connected_line_macro ( struct  ast_channel  * autoservice_chan ,  struct  ast_channel  * macro_chan ,  const  void  * connected_info ,  int  is_caller ,  int  is_frame ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * macro ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * macro_args ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  retval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( macro_chan ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									macro  =  pbx_builtin_getvar_helper ( macro_chan ,  is_caller 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-25 16:23:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										?  " CONNECTED_LINE_CALLER_SEND_MACRO "  :  " CONNECTED_LINE_CALLEE_SEND_MACRO " ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									macro  =  ast_strdupa ( S_OR ( macro ,  " " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									macro_args  =  pbx_builtin_getvar_helper ( macro_chan ,  is_caller 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-26 20:04:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										?  " CONNECTED_LINE_CALLER_SEND_MACRO_ARGS "  :  " CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS " ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									macro_args  =  ast_strdupa ( S_OR ( macro_args ,  " " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ast_strlen_zero ( macro ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-21 20:29:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( macro_chan ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( is_frame )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										const  struct  ast_frame  * frame  =  connected_info ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-25 16:23:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_connected_line_parse_data ( frame - > data . ptr ,  frame - > datalen ,  & macro_chan - > connected ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										const  struct  ast_party_connected_line  * connected  =  connected_info ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-05-25 16:23:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_party_connected_line_copy ( & macro_chan - > connected ,  connected ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-21 20:29:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( macro_chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( ! ( retval  =  ast_app_run_macro ( autoservice_chan ,  macro_chan ,  macro ,  macro_args ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-21 20:29:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_lock ( macro_chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_update_connected_line ( macro_chan ,  & macro_chan - > connected ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-21 20:29:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( macro_chan ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  retval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_redirecting_macro ( struct  ast_channel  * autoservice_chan ,  struct  ast_channel  * macro_chan ,  const  void  * redirecting_info ,  int  is_caller ,  int  is_frame ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * macro ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  char  * macro_args ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  retval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_lock ( macro_chan ) ; 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									macro  =  pbx_builtin_getvar_helper ( macro_chan ,  is_caller 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										?  " REDIRECTING_CALLER_SEND_MACRO "  :  " REDIRECTING_CALLEE_SEND_MACRO " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									macro  =  ast_strdupa ( S_OR ( macro ,  " " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									macro_args  =  pbx_builtin_getvar_helper ( macro_chan ,  is_caller 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										?  " REDIRECTING_CALLER_SEND_MACRO_ARGS "  :  " REDIRECTING_CALLEE_SEND_MACRO_ARGS " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									macro_args  =  ast_strdupa ( S_OR ( macro_args ,  " " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ast_strlen_zero ( macro ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-21 20:29:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( macro_chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									if  ( is_frame )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										const  struct  ast_frame  * frame  =  redirecting_info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_redirecting_parse_data ( frame - > data . ptr ,  frame - > datalen ,  & macro_chan - > redirecting ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									}  else  { 
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										const  struct  ast_party_redirecting  * redirecting  =  redirecting_info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_party_redirecting_copy ( & macro_chan - > redirecting ,  redirecting ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-21 20:29:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									ast_channel_unlock ( macro_chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Enhancements to connected line and redirecting work.
From reviewboard:
Digium has a commercial customer who has made extensive use of the connected party and
redirecting information present in later versions of Asterisk Business Edition and which
is to be in the upcoming 1.8 release. Through their use of the feature, new problems and solutions
have come about. This patch adds several enhancements to maximize usage of the connected party
and redirecting information functionality.
First, Asterisk trunk already had connected line interception macros. These macros allow you to
manipulate connected line information before it was sent out to its target. This patch adds the
same feature except for redirecting information instead.
Second, the ast_callerid and ast_party_id structures have been enhanced to provide a "tag." This
tag can be set with func_callerid, func_connectedline, func_redirecting, and in the case of DAHDI,
mISDN, and SIP channels, can be set in a configuration file. The idea behind the callerid tag is
that it can be set to whatever value the administrator likes. Later, when running connected line
and redirecting macros, the admin can read the tag off the appropriate structure to determine what
action to take. You can think of this sort of like a channel variable, except that instead of having
the variable associated with a channel, the variable is associated with a specific identity within
Asterisk.
Third, app_dial has two new options, s and u. The s option lets a dialplan writer force a specific
caller ID tag to be placed on the outgoing channel. The u option allows the dialplan writer to force
a specific calling presentation value on the outgoing channel.
Fourth, there is a new control frame subclass called AST_CONTROL_READ_ACTION added. This was added
to correct a very specific situation. In the case of SIP semi-attended (blond) transfers, the party
being transferred would not have the opportunity to run a connected line interception macro to
possibly alter the transfer target's connected line information. The issue here was that during a
blond transfer, the SIP transfer code has no bridged channel on which to queue the connected line
update. The way this was corrected was to add this new control frame subclass. Now, we queue an
AST_CONTROL_READ_ACTION frame on the channel on which the connected line interception macro should
be run. When ast_read is called to read the frame, ast_read responds by calling a callback function
associated with the specific read action the control frame describes. In this case, the action taken
is to run the connected line interception macro on the transferee's channel.
Review: https://reviewboard.asterisk.org/r/652/
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@263541 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-05-17 15:36:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									retval  =  ast_app_run_macro ( autoservice_chan ,  macro_chan ,  macro ,  macro_args ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! retval )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-21 20:29:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_lock ( macro_chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-14 15:48:36 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_update_redirecting ( macro_chan ,  & macro_chan - > redirecting ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-21 20:29:51 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
										ast_channel_unlock ( macro_chan ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-01 20:57:31 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  retval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
											 
										 
										
											
												Merge Call completion support into trunk.
From Reviewboard:
CCSS stands for Call Completion Supplementary Services. An admittedly out-of-date
overview of the architecture can be found in the file doc/CCSS_architecture.pdf
in the CCSS branch. Off the top of my head, the big differences between what is
implemented and what is in the document are as follows:
1. We did not end up modifying the Hangup application at all.
2. The document states that a single call completion monitor may be used across
   multiple calls to the same device. This proved to not be such a good idea
   when implementing protocol-specific monitors, and so we ended up using one
   monitor per-device per-call.
3. There are some configuration options which were conceived after the document
   was written. These are documented in the ccss.conf.sample that is on this
   review request.
		      
For some basic understanding of terminology used throughout this code, see the
ccss.tex document that is on this review.
This implements CCBS and CCNR in several flavors.
First up is a "generic" implementation, which can work over any channel technology
provided that the channel technology can accurately report device state. Call
completion is requested using the dialplan application CallCompletionRequest and can
be canceled using CallCompletionCancel. Device state subscriptions are used in order
to monitor the state of called parties.
Next, there is a SIP-specific implementation of call completion. This method uses the
methods outlined in draft-ietf-bliss-call-completion-06 to implement call completion
using SIP signaling. There are a few things to note here:
* The agent/monitor terminology used throughout Asterisk sometimes is the reverse of
  what is defined in the referenced draft.
* Implementation of the draft required support for SIP PUBLISH. I attempted to write
  this in a generic-enough fashion such that if someone were to want to write PUBLISH
  support for other event packages, such as dialog-state or presence, most of the effort
  would be in writing callbacks specific to the event package.
* A subportion of supporting PUBLISH reception was that we had to implement a PIDF
  parser. The PIDF support added is a bit minimal. I first wrote a validation
  routine to ensure that the PIDF document is formatted properly. The rest of the
  PIDF reading is done in-line in the call-completion-specific PUBLISH-handling
  code. In other words, while there is PIDF support here, it is not in any state
  where it could easily be applied to other event packages as is.
Finally, there are a variety of ISDN-related call completion protocols supported. These
were written by Richard Mudgett, and as such I can't really say much about their
implementation. There are notes in the CHANGES file that indicate the ISDN protocols
over which call completion is supported.
Review: https://reviewboard.asterisk.org/r/523
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256528 65c4cc65-6c06-0410-ace0-fbb531ad65f3
											 
										 
										
											2010-04-09 15:31:32 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  * channel_cc_params_copy ( void  * data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									const  struct  ast_cc_config_params  * src  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_cc_config_params  * dest  =  ast_cc_config_params_init ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! dest )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_cc_copy_config_params ( dest ,  src ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  dest ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  void  channel_cc_params_destroy ( void  * data ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_cc_config_params  * cc_params  =  data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_cc_config_params_destroy ( cc_params ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								static  const  struct  ast_datastore_info  cc_channel_datastore_info  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. type  =  " Call Completion " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. duplicate  =  channel_cc_params_copy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									. destroy  =  channel_cc_params_destroy , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_cc_params_init ( struct  ast_channel  * chan , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										const  struct  ast_cc_config_params  * base_params ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_cc_config_params  * cc_params ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * cc_datastore ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ( cc_params  =  ast_cc_config_params_init ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ( cc_datastore  =  ast_datastore_alloc ( & cc_channel_datastore_info ,  NULL ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_cc_config_params_destroy ( cc_params ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( base_params )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										ast_cc_copy_config_params ( cc_params ,  base_params ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									cc_datastore - > data  =  cc_params ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_channel_datastore_add ( chan ,  cc_datastore ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  ast_cc_config_params  * ast_channel_get_cc_config_params ( struct  ast_channel  * chan ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_datastore  * cc_datastore ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ( cc_datastore  =  ast_channel_datastore_find ( chan ,  & cc_channel_datastore_info ,  NULL ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										/* If we can't find the datastore, it almost definitely means that the channel type being
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  used  has  not  had  its  driver  modified  to  parse  CC  config  parameters .  The  best  action 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 *  to  take  here  is  to  create  the  parameters  on  the  spot  with  the  defaults  set . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ast_channel_cc_params_init ( chan ,  NULL ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										if  ( ! ( cc_datastore  =  ast_channel_datastore_find ( chan ,  & cc_channel_datastore_info ,  NULL ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											/* Should be impossible */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_assert ( cc_datastore - > data  ! =  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  cc_datastore - > data ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_get_device_name ( struct  ast_channel  * chan ,  char  * device_name ,  size_t  name_buffer_length ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  len  =  name_buffer_length ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  * dash ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_channel_queryoption ( chan ,  AST_OPTION_DEVICE_NAME ,  device_name ,  & len ,  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									/* Dang. Do it the old-fashioned way */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_copy_string ( device_name ,  chan - > name ,  name_buffer_length ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( dash  =  strrchr ( device_name ,  ' - ' ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* dash  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  ast_channel_get_cc_agent_type ( struct  ast_channel  * chan ,  char  * agent_type ,  size_t  size ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									int  len  =  size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									char  * slash ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ! ast_channel_queryoption ( chan ,  AST_OPTION_CC_AGENT_TYPE ,  agent_type ,  & len ,  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									ast_copy_string ( agent_type ,  chan - > name ,  size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									if  ( ( slash  =  strchr ( agent_type ,  ' / ' ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
										* slash  =  ' \0 ' ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 10:34:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* DO NOT PUT ADDITIONAL FUNCTIONS BELOW THIS BOUNDARY
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  ONLY  FUNCTIONS  FOR  PROVIDING  BACKWARDS  ABI  COMPATIBILITY  BELONG  HERE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Provide binary compatibility for modules that call ast_channel_alloc() directly;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  newly  compiled  modules  will  call  __ast_channel_alloc ( )  via  the  macros  in  channel . h 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# undef ast_channel_alloc 
 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  __attribute__ ( ( format ( printf ,  10 ,  11 ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 10:34:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									* ast_channel_alloc ( int  needqueue ,  int  state ,  const  char  * cid_num , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											   const  char  * cid_name ,  const  char  * acctcode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											   const  char  * exten ,  const  char  * context , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
											   const  char  * linkedid ,  const  int  amaflag , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
											   const  char  * name_fmt ,  . . . ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 10:34:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  ast_channel  * ast_channel_alloc ( int  needqueue ,  int  state ,  const  char  * cid_num , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												      const  char  * cid_name ,  const  char  * acctcode , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												      const  char  * exten ,  const  char  * context , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
												      const  char  * linkedid ,  const  int  amaflag , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
												      const  char  * name_fmt ,  . . . ) 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 10:34:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									va_list  ap1 ,  ap2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									struct  ast_channel  * result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									va_start ( ap1 ,  name_fmt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									va_start ( ap2 ,  name_fmt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									result  =  __ast_channel_alloc_ap ( needqueue ,  state ,  cid_num ,  cid_name ,  acctcode ,  exten ,  context , 
							 
						 
					
						
							
								
									
										
										
										
											2009-06-26 15:28:53 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
													linkedid ,  amaflag ,  __FILE__ ,  __LINE__ ,  __FUNCTION__ ,  name_fmt ,  ap1 ,  ap2 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2009-05-05 10:34:19 +00:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
									va_end ( ap1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									va_end ( ap2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
									return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								}