Sun Jun 12 16:37:56 2011

Asterisk developer's documentation


channel.h File Reference

General Asterisk PBX channel definitions. More...

#include "asterisk/abstract_jb.h"
#include <unistd.h>
#include <sys/poll.h>
#include "asterisk/compat.h"
#include "asterisk/frame.h"
#include "asterisk/sched.h"
#include "asterisk/chanvars.h"
#include "asterisk/config.h"
#include "asterisk/lock.h"
#include "asterisk/cdr.h"
#include "asterisk/utils.h"
#include "asterisk/linkedlists.h"
#include "asterisk/stringfields.h"
#include "asterisk/compiler.h"

Include dependency graph for channel.h:

Go to the source code of this file.

Data Structures

struct  ast_bridge_config
struct  ast_callerid
 Structure for all kinds of caller ID identifications. More...
struct  ast_channel
 Main Channel structure associated with a channel. This is the side of it mostly used by the pbx and call management. More...
struct  ast_channel_tech
 Structure to describe a channel "technology", ie a channel driver See for examples:. More...
struct  ast_datastore
 Structure for a channel data store. More...
struct  ast_datastore_info
 Structure for a data store type. More...
struct  ast_generator
struct  outgoing_helper

Defines

#define AST_AGENT_FD   (AST_MAX_FDS-3)
#define AST_ALERT_FD   (AST_MAX_FDS-1)
#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)
 Report DTMF on channel 0.
#define AST_BRIDGE_DTMF_CHANNEL_1   (1 << 1)
 Report DTMF on channel 1.
#define AST_BRIDGE_IGNORE_SIGS   (1 << 4)
 Ignore all signal frames except NULL.
#define AST_BRIDGE_REC_CHANNEL_0   (1 << 2)
 Return all voice frames on channel 0.
#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)
 Return all voice frames on channel 1.
#define AST_CHANNEL_NAME   80
#define AST_GENERATOR_FD   (AST_MAX_FDS-4)
#define AST_MAX_CONTEXT   80
#define AST_MAX_EXTENSION   80
#define AST_MAX_FDS   8
#define AST_MAX_UNIQUEID   64
#define AST_TIMING_FD   (AST_MAX_FDS-2)
#define CHECK_BLOCKING(c)
#define DATASTORE_INHERIT_FOREVER   INT_MAX
#define DEBUGCHAN_FLAG   0x80000000
#define FRAMECOUNT_INC(x)   ( ((x) & DEBUGCHAN_FLAG) | (((x)+1) & ~DEBUGCHAN_FLAG) )
#define LOAD_OH(oh)
#define MAX_LANGUAGE   20
#define MAX_MUSICCLASS   80

Typedefs

typedef unsigned long long ast_group_t

Enumerations

enum  { AST_CHAN_TP_WANTSJITTER = (1 << 0), AST_CHAN_TP_CREATESJITTER = (1 << 1) }
 ast_channel_tech Properties More...
enum  {
  AST_FLAG_DEFER_DTMF = (1 << 1), AST_FLAG_WRITE_INT = (1 << 2), AST_FLAG_BLOCKING = (1 << 3), AST_FLAG_ZOMBIE = (1 << 4),
  AST_FLAG_EXCEPTION = (1 << 5), AST_FLAG_MOH = (1 << 6), AST_FLAG_SPYING = (1 << 7), AST_FLAG_NBRIDGE = (1 << 8),
  AST_FLAG_IN_AUTOLOOP = (1 << 9), AST_FLAG_OUTGOING = (1 << 10), AST_FLAG_WHISPER = (1 << 11), AST_FLAG_IN_DTMF = (1 << 12),
  AST_FLAG_EMULATE_DTMF = (1 << 13), AST_FLAG_END_DTMF_ONLY = (1 << 14), AST_FLAG_MASQ_NOSTREAM = (1 << 15)
}
 ast_channel flags More...
enum  {
  AST_FEATURE_PLAY_WARNING = (1 << 0), AST_FEATURE_REDIRECT = (1 << 1), AST_FEATURE_DISCONNECT = (1 << 2), AST_FEATURE_ATXFER = (1 << 3),
  AST_FEATURE_AUTOMON = (1 << 4), AST_FEATURE_PARKCALL = (1 << 5)
}
 ast_bridge_config flags More...
enum  { AST_CDR_TRANSFER = (1 << 0), AST_CDR_FORWARD = (1 << 1), AST_CDR_CALLWAIT = (1 << 2), AST_CDR_CONFERENCE = (1 << 3) }
enum  {
  AST_SOFTHANGUP_DEV = (1 << 0), AST_SOFTHANGUP_ASYNCGOTO = (1 << 1), AST_SOFTHANGUP_SHUTDOWN = (1 << 2), AST_SOFTHANGUP_TIMEOUT = (1 << 3),
  AST_SOFTHANGUP_APPUNLOAD = (1 << 4), AST_SOFTHANGUP_EXPLICIT = (1 << 5), AST_SOFTHANGUP_UNBRIDGE = (1 << 6)
}
enum  ast_bridge_result { AST_BRIDGE_COMPLETE = 0, AST_BRIDGE_FAILED = -1, AST_BRIDGE_FAILED_NOWARN = -2, AST_BRIDGE_RETRY = -3 }
enum  ast_channel_adsicpe { AST_ADSI_UNKNOWN, AST_ADSI_AVAILABLE, AST_ADSI_UNAVAILABLE, AST_ADSI_OFFHOOKONLY }
enum  ast_channel_state {
  AST_STATE_DOWN, AST_STATE_RESERVED, AST_STATE_OFFHOOK, AST_STATE_DIALING,
  AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, AST_STATE_BUSY,
  AST_STATE_DIALING_OFFHOOK, AST_STATE_PRERING, AST_STATE_MUTE = (1 << 16)
}
 ast_channel states More...
enum  channelreloadreason { CHANNEL_MODULE_LOAD, CHANNEL_MODULE_RELOAD, CHANNEL_CLI_RELOAD, CHANNEL_MANAGER_RELOAD }
 Channel reload reasons for manager events at load or reload of configuration. More...

Functions

struct ast_channel__ast_request_and_dial (const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname, struct outgoing_helper *oh)
struct ast_channel__ast_request_and_dial_uniqueid (const char *type, int format, void *data, int timeout, int *reason, int callingpres, const char *cidnum, const char *cidname, struct outgoing_helper *oh, char *uniqueid)
int ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params)
int ast_active_channels (void)
 returns number of active/allocated channels
static int ast_add_fd (struct pollfd *pfd, int fd)
 if fd is a valid descriptor, set *pfd with the descriptor
char * ast_alloc_uniqueid (void)
 Create a uniqueid.
int ast_answer (struct ast_channel *chan)
 Answer a ringing call.
int ast_autoservice_start (struct ast_channel *chan)
 Automatically service a channel for us...
int ast_autoservice_stop (struct ast_channel *chan)
 Stop servicing a channel for us...
void ast_begin_shutdown (int hangup)
 Initiate system shutdown.
int ast_best_codec (int fmts)
 Pick the best audio codec.
struct ast_channelast_bridged_channel (struct ast_channel *chan)
 Find bridged channel.
int ast_call (struct ast_channel *chan, char *addr, int timeout)
 Make a call.
void ast_cancel_shutdown (void)
 Cancel a shutdown in progress.
const char * ast_cause2str (int state) attribute_pure
 Gives the string form of a given hangup cause.
void ast_change_name (struct ast_channel *chan, char *newname)
 Change channel name.
struct ast_channelast_channel_alloc (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *name_fmt,...)
 Create a channel structure.
int ast_channel_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
 Bridge two channels together.
int ast_channel_cmpwhentohangup (struct ast_channel *chan, time_t offset)
 Compare a offset with the settings of when to hang a channel up.
int ast_channel_datastore_add (struct ast_channel *chan, struct ast_datastore *datastore)
 Add a datastore to a channel.
struct ast_datastoreast_channel_datastore_alloc (const struct ast_datastore_info *info, char *uid)
 Create a channel datastore structure.
struct ast_datastoreast_channel_datastore_find (struct ast_channel *chan, const struct ast_datastore_info *info, char *uid)
 Find a datastore on a channel.
int ast_channel_datastore_free (struct ast_datastore *datastore)
 Free a channel datastore structure.
int ast_channel_datastore_inherit (struct ast_channel *from, struct ast_channel *to)
 Inherit datastores from a parent to a child.
int ast_channel_datastore_remove (struct ast_channel *chan, struct ast_datastore *datastore)
 Remove a datastore from a channel.
int ast_channel_defer_dtmf (struct ast_channel *chan)
 Set defer DTMF flag on channel.
void ast_channel_free (struct ast_channel *)
 Free a channel structure.
void ast_channel_inherit_variables (const struct ast_channel *parent, struct ast_channel *child)
 Inherits channel variable from parent to child channel.
int ast_channel_make_compatible (struct ast_channel *c0, struct ast_channel *c1)
 Makes two channel formats compatible.
int ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone)
 Weird function made for call transfers.
struct ast_frameast_channel_queryoption (struct ast_channel *channel, int option, void *data, int *datalen, int block)
char * ast_channel_reason2str (int reason)
 return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument
int ast_channel_register (const struct ast_channel_tech *tech)
 Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
int ast_channel_sendhtml (struct ast_channel *channel, int subclass, const char *data, int datalen)
int ast_channel_sendurl (struct ast_channel *channel, const char *url)
int ast_channel_setoption (struct ast_channel *channel, int option, void *data, int datalen, int block)
 Sets an option on a channel.
void ast_channel_setwhentohangup (struct ast_channel *chan, time_t offset)
 Set when to hang a channel up.
struct ast_silence_generatorast_channel_start_silence_generator (struct ast_channel *chan)
 Starts a silence generator on the given channel.
void ast_channel_stop_silence_generator (struct ast_channel *chan, struct ast_silence_generator *state)
 Stops a previously-started silence generator on the given channel.
int ast_channel_supports_html (struct ast_channel *channel)
void ast_channel_undefer_dtmf (struct ast_channel *chan)
 Unset defer DTMF flag on channel.
void ast_channel_unregister (const struct ast_channel_tech *tech)
 Unregister a channel technology.
struct ast_channelast_channel_walk_locked (const struct ast_channel *prev)
 Browse channels in use Browse the channels currently in use.
int ast_channel_whisper_feed (struct ast_channel *chan, struct ast_frame *f)
 Feed an audio frame into the whisper buffer on a channel.
int ast_channel_whisper_start (struct ast_channel *chan)
 Begin 'whispering' onto a channel.
void ast_channel_whisper_stop (struct ast_channel *chan)
 Stop 'whispering' onto a channel.
struct ast_variableast_channeltype_list (void)
 return an ast_variable list of channeltypes
int ast_check_hangup (struct ast_channel *chan)
 Check to see if a channel is needing hang up.
void ast_deactivate_generator (struct ast_channel *chan)
int ast_do_masquerade (struct ast_channel *chan)
 Start masquerading a channel XXX This is a seriously wacked out operation. We're essentially putting the guts of the clone channel into the original channel. Start by killing off the original channel's backend. I'm not sure we're going to keep this function, because while the features are nice, the cost is very high in terms of pure nastiness. XXX.
static int ast_fdisset (struct pollfd *pfds, int fd, int max, int *start)
 Helper function for migrating select to poll.
struct ast_channelast_get_channel_by_exten_locked (const char *exten, const char *context)
 Get channel by exten (and optionally context) and lock it.
struct ast_channelast_get_channel_by_name_locked (const char *chan)
 Get channel by name (locks channel).
struct ast_channelast_get_channel_by_name_prefix_locked (const char *name, const int namelen)
 Get channel by name prefix (locks channel).
struct ast_channelast_get_channel_by_uniqueid_locked (const char *uniqueid)
struct ast_channel_techast_get_channel_tech (const char *name)
 Get a channel technology structure by name.
ast_group_t ast_get_group (const char *s)
int ast_hangup (struct ast_channel *chan)
 Hang up a channel.
int ast_indicate (struct ast_channel *chan, int condition)
 Indicates condition of channel.
int ast_indicate_data (struct ast_channel *chan, int condition, const void *data, size_t datalen)
 Indicates condition of channel, with payload.
int ast_internal_timing_enabled (struct ast_channel *chan)
 Check if the channel can run in internal timing mode.
char * ast_print_group (char *buf, int buflen, ast_group_t group)
 print call- and pickup groups into buffer
int ast_prod (struct ast_channel *chan)
 Send empty audio to prime a channel driver.
int ast_queue_control (struct ast_channel *chan, enum ast_control_frame_type control)
 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)
 Queue a control frame with payload.
int ast_queue_frame (struct ast_channel *chan, struct ast_frame *f)
 Queue an outgoing frame.
int ast_queue_hangup (struct ast_channel *chan)
 Queue a hangup frame.
struct ast_frameast_read (struct ast_channel *chan)
 Reads a frame.
struct ast_frameast_read_noaudio (struct ast_channel *chan)
 Reads a frame, returning AST_FRAME_NULL frame if audio. Read a frame.
int ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders)
int ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int rtimeout, char *enders, int audiofd, int ctrlfd)
int ast_recvchar (struct ast_channel *chan, int timeout)
 Receives a text character from a channel.
char * ast_recvtext (struct ast_channel *chan, int timeout)
 Receives a text string from a channel Read a string of text from a channel.
struct ast_channelast_request (const char *type, int format, void *data, int *status)
 Requests a channel.
struct ast_channelast_request_and_dial (const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname)
 Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
struct ast_channelast_request_and_dial_uniqueid (const char *type, int format, void *data, int timeout, int *reason, int callingpres, const char *cidnum, const char *cidname, char *uniqueid)
struct ast_channelast_request_with_uniqueid (const char *type, int format, void *data, int *status, char *uniqueid)
 Requests a channel.
int ast_safe_sleep (struct ast_channel *chan, int ms)
 Wait for a specied amount of time, looking for hangups.
int ast_safe_sleep_conditional (struct ast_channel *chan, int ms, int(*cond)(void *), void *data)
 Wait for a specied amount of time, looking for hangups and a condition argument.
char * ast_safe_string_alloc (const char *fmt,...)
 printf the string into a correctly sized mallocd buffer, and return the buffer
static int ast_select (int nfds, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tvp)
 Waits for activity on a group of channels.
int ast_send_message (const char *type, void *data, char *to, char *from, char *message, int ispdu)
 "Requests" a channel for sending a message
int ast_senddigit (struct ast_channel *chan, char digit)
 Send a DTMF digit to a channel Send a DTMF digit to a channel.
int ast_senddigit_begin (struct ast_channel *chan, char digit)
int ast_senddigit_end (struct ast_channel *chan, char digit, unsigned int duration)
int ast_sendmessage (struct ast_channel *chan, const char *dest, const char *text, int ispdu)
 Sends message to a channel Write text to a display on a channel.
int ast_sendtext (struct ast_channel *chan, const char *text)
 Sends text to a channel Write text to a display on a channel.
void ast_set_callerid (struct ast_channel *chan, const char *cidnum, const char *cidname, const char *ani)
int ast_set_read_format (struct ast_channel *chan, int format)
 Sets read format on channel chan Set read format for channel to whichever component of "format" is best.
void ast_set_variables (struct ast_channel *chan, struct ast_variable *vars)
 adds a list of channel variables to a channel
int ast_set_write_format (struct ast_channel *chan, int format)
 Sets write format on channel chan Set write format for channel to whichever compoent of "format" is best.
int ast_setstate (struct ast_channel *chan, enum ast_channel_state state)
 Change the state of a channel.
int ast_setstate_and_callerid (struct ast_channel *chan, enum ast_channel_state state, char *cid_num, char *cid_name)
 Change the state of a channel and the callerid of the calling channel.
int ast_settimeout (struct ast_channel *c, int samples, int(*func)(const void *data), void *data)
int ast_shutting_down (void)
 Returns non-zero if Asterisk is being shut down.
int ast_softhangup (struct ast_channel *chan, int cause)
 Softly hangup up a channel.
int ast_softhangup_nolock (struct ast_channel *chan, int cause)
 Softly hangup up a channel (no channel lock).
char * ast_state2str (enum ast_channel_state)
 Gives the string form of a given channel state.
int ast_str2cause (const char *name) attribute_pure
 Convert a symbolic hangup cause to number.
int ast_tonepair (struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
int ast_tonepair_start (struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
void ast_tonepair_stop (struct ast_channel *chan)
int ast_transfer (struct ast_channel *chan, char *dest)
 Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.
char * ast_transfercapability2str (int transfercapability) attribute_const
 Gives the string form of a given transfer capability.
int ast_waitfor (struct ast_channel *chan, int ms)
 Wait for input on a channel.
struct ast_channelast_waitfor_n (struct ast_channel **chan, int n, int *ms)
 Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds.
int ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception)
 Waits for input on an fd This version works on fd's only. Be careful with it.
struct ast_channelast_waitfor_nandfds (struct ast_channel **chan, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
 Waits for activity on a group of channels.
int ast_waitfordigit (struct ast_channel *c, int ms)
 Waits for a digit.
int ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int ctrlfd)
 Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
struct ast_channelast_walk_channel_by_exten_locked (const struct ast_channel *chan, const char *exten, const char *context)
 Get next channel by exten (and optionally context) and lock it.
struct ast_channelast_walk_channel_by_name_prefix_locked (const struct ast_channel *chan, const char *name, const int namelen)
 Get channel by name prefix (locks channel).
int ast_write (struct ast_channel *chan, struct ast_frame *frame)
 Write a frame to a channel This function writes the given frame to the indicated channel.
int ast_write_video (struct ast_channel *chan, struct ast_frame *frame)
 Write video frame to a channel This function writes the given frame to the indicated channel.
const char * channelreloadreason2txt (enum channelreloadreason reason)
 Convert enum channelreloadreason to text string for manager event.

Variables

ast_mutex_t uniquelock


Detailed Description

General Asterisk PBX channel definitions.

See also:

Definition in file channel.h.


Define Documentation

#define AST_AGENT_FD   (AST_MAX_FDS-3)

used by agents for pass through

Definition at line 133 of file channel.h.

Referenced by agent_read().

#define AST_ALERT_FD   (AST_MAX_FDS-1)

used for alertpipe

Definition at line 131 of file channel.h.

Referenced by ast_channel_alloc(), and restore_channel().

#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)

#define AST_BRIDGE_DTMF_CHANNEL_1   (1 << 1)

#define AST_BRIDGE_IGNORE_SIGS   (1 << 4)

Ignore all signal frames except NULL.

Definition at line 1056 of file channel.h.

Referenced by ast_generic_bridge(), bridge_native_loop(), bridge_p2p_loop(), and iax2_bridge().

#define AST_BRIDGE_REC_CHANNEL_0   (1 << 2)

Return all voice frames on channel 0.

Definition at line 1052 of file channel.h.

#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)

Return all voice frames on channel 1.

Definition at line 1054 of file channel.h.

#define AST_CHANNEL_NAME   80

Max length of an ast_channel name

Definition at line 108 of file channel.h.

Referenced by ast_channel_free(), ast_parse_device_state(), create_jb(), fast_originate(), page_exec(), and softhangup_exec().

#define AST_GENERATOR_FD   (AST_MAX_FDS-4)

used by generator

Definition at line 134 of file channel.h.

Referenced by __ast_read(), ast_deactivate_generator(), and ast_do_masquerade().

#define AST_MAX_CONTEXT   80

Max length of a context

Definition at line 107 of file channel.h.

Referenced by _macro_exec(), cleanup_stale_contexts(), conf_run(), gtalk_load_config(), reload_config(), and try_calling().

#define AST_MAX_EXTENSION   80

#define AST_MAX_FDS   8

#define AST_MAX_UNIQUEID   64

Definition at line 93 of file channel.h.

#define AST_TIMING_FD   (AST_MAX_FDS-2)

used for timingfd

Definition at line 132 of file channel.h.

Referenced by __ast_read(), agent_read(), ast_channel_alloc(), ast_do_masquerade(), and restore_channel().

#define CHECK_BLOCKING (  ) 

#define DATASTORE_INHERIT_FOREVER   INT_MAX

Definition at line 124 of file channel.h.

Referenced by ast_channel_datastore_inherit(), and try_calling().

#define DEBUGCHAN_FLAG   0x80000000

#define FRAMECOUNT_INC (  )     ( ((x) & DEBUGCHAN_FLAG) | (((x)+1) & ~DEBUGCHAN_FLAG) )

Definition at line 306 of file channel.h.

Referenced by __ast_read(), and ast_write().

#define LOAD_OH ( oh   ) 

Definition at line 551 of file channel.h.

Referenced by ast_pbx_outgoing_exten_uniqueid().

#define MAX_LANGUAGE   20

Max length of the language setting

Definition at line 109 of file channel.h.

#define MAX_MUSICCLASS   80

Max length of the music class setting

Definition at line 110 of file channel.h.


Typedef Documentation

typedef unsigned long long ast_group_t

Definition at line 143 of file channel.h.


Enumeration Type Documentation

anonymous enum

ast_channel_tech Properties

Enumerator:
AST_CHAN_TP_WANTSJITTER  Channels have this property if they can accept input with jitter; i.e. most VoIP channels.
AST_CHAN_TP_CREATESJITTER  Channels have this property if they can create jitter; i.e. most VoIP channels.

Definition at line 476 of file channel.h.

00476      {
00477    /*! \brief Channels have this property if they can accept input with jitter; 
00478     *         i.e. most VoIP channels */
00479    AST_CHAN_TP_WANTSJITTER = (1 << 0),
00480    /*! \brief Channels have this property if they can create jitter; 
00481     *         i.e. most VoIP channels */
00482    AST_CHAN_TP_CREATESJITTER = (1 << 1),
00483 };

anonymous enum

ast_channel flags

Enumerator:
AST_FLAG_DEFER_DTMF  Queue incoming dtmf, to be released when this flag is turned off
AST_FLAG_WRITE_INT  write should be interrupt generator
AST_FLAG_BLOCKING  a thread is blocking on this channel
AST_FLAG_ZOMBIE  This is a zombie channel
AST_FLAG_EXCEPTION  There is an exception pending
AST_FLAG_MOH  Listening to moh XXX anthm promises me this will disappear XXX
AST_FLAG_SPYING  This channel is spying on another channel
AST_FLAG_NBRIDGE  This channel is in a native bridge
AST_FLAG_IN_AUTOLOOP  the channel is in an auto-incrementing dialplan processor, so when ->priority is set, it will get incremented before finding the next priority to run
AST_FLAG_OUTGOING  This is an outgoing call
AST_FLAG_WHISPER  This channel is being whispered on
AST_FLAG_IN_DTMF  A DTMF_BEGIN frame has been read from this channel, but not yet an END
AST_FLAG_EMULATE_DTMF  A DTMF_END was received when not IN_DTMF, so the length of the digit is currently being emulated
AST_FLAG_END_DTMF_ONLY  This is set to tell the channel not to generate DTMF begin frames, and to instead only generate END frames.
AST_FLAG_MASQ_NOSTREAM  This flag indicates that on a masquerade, an active stream should not be carried over

Definition at line 486 of file channel.h.

00486      {
00487    /*! Queue incoming dtmf, to be released when this flag is turned off */
00488    AST_FLAG_DEFER_DTMF =    (1 << 1),
00489    /*! write should be interrupt generator */
00490    AST_FLAG_WRITE_INT =     (1 << 2),
00491    /*! a thread is blocking on this channel */
00492    AST_FLAG_BLOCKING =      (1 << 3),
00493    /*! This is a zombie channel */
00494    AST_FLAG_ZOMBIE =        (1 << 4),
00495    /*! There is an exception pending */
00496    AST_FLAG_EXCEPTION =     (1 << 5),
00497    /*! Listening to moh XXX anthm promises me this will disappear XXX */
00498    AST_FLAG_MOH =           (1 << 6),
00499    /*! This channel is spying on another channel */
00500    AST_FLAG_SPYING =        (1 << 7),
00501    /*! This channel is in a native bridge */
00502    AST_FLAG_NBRIDGE =       (1 << 8),
00503    /*! the channel is in an auto-incrementing dialplan processor,
00504     *  so when ->priority is set, it will get incremented before
00505     *  finding the next priority to run */
00506    AST_FLAG_IN_AUTOLOOP =   (1 << 9),
00507    /*! This is an outgoing call */
00508    AST_FLAG_OUTGOING =      (1 << 10),
00509    /*! This channel is being whispered on */
00510    AST_FLAG_WHISPER =       (1 << 11),
00511    /*! A DTMF_BEGIN frame has been read from this channel, but not yet an END */
00512    AST_FLAG_IN_DTMF =       (1 << 12),
00513    /*! A DTMF_END was received when not IN_DTMF, so the length of the digit is 
00514     *  currently being emulated */
00515    AST_FLAG_EMULATE_DTMF =  (1 << 13),
00516    /*! This is set to tell the channel not to generate DTMF begin frames, and
00517     *  to instead only generate END frames. */
00518    AST_FLAG_END_DTMF_ONLY = (1 << 14),
00519    /*! This flag indicates that on a masquerade, an active stream should not
00520     *  be carried over */
00521    AST_FLAG_MASQ_NOSTREAM = (1 << 15),
00522 };

anonymous enum

ast_bridge_config flags

Enumerator:
AST_FEATURE_PLAY_WARNING 
AST_FEATURE_REDIRECT 
AST_FEATURE_DISCONNECT 
AST_FEATURE_ATXFER 
AST_FEATURE_AUTOMON 
AST_FEATURE_PARKCALL 

Definition at line 525 of file channel.h.

00525      {
00526    AST_FEATURE_PLAY_WARNING = (1 << 0),
00527    AST_FEATURE_REDIRECT =     (1 << 1),
00528    AST_FEATURE_DISCONNECT =   (1 << 2),
00529    AST_FEATURE_ATXFER =       (1 << 3),
00530    AST_FEATURE_AUTOMON =      (1 << 4),
00531    AST_FEATURE_PARKCALL =     (1 << 5),
00532 };

anonymous enum

Enumerator:
AST_CDR_TRANSFER 
AST_CDR_FORWARD 
AST_CDR_CALLWAIT 
AST_CDR_CONFERENCE 

Definition at line 573 of file channel.h.

00573      {
00574    AST_CDR_TRANSFER =   (1 << 0),
00575    AST_CDR_FORWARD =    (1 << 1),
00576    AST_CDR_CALLWAIT =   (1 << 2),
00577    AST_CDR_CONFERENCE = (1 << 3),
00578 };

anonymous enum

Enumerator:
AST_SOFTHANGUP_DEV  Soft hangup by device
AST_SOFTHANGUP_ASYNCGOTO  Soft hangup for async goto
AST_SOFTHANGUP_SHUTDOWN 
AST_SOFTHANGUP_TIMEOUT 
AST_SOFTHANGUP_APPUNLOAD 
AST_SOFTHANGUP_EXPLICIT 
AST_SOFTHANGUP_UNBRIDGE 

Definition at line 580 of file channel.h.

00580      {
00581    /*! Soft hangup by device */
00582    AST_SOFTHANGUP_DEV =       (1 << 0),
00583    /*! Soft hangup for async goto */
00584    AST_SOFTHANGUP_ASYNCGOTO = (1 << 1),
00585    AST_SOFTHANGUP_SHUTDOWN =  (1 << 2),
00586    AST_SOFTHANGUP_TIMEOUT =   (1 << 3),
00587    AST_SOFTHANGUP_APPUNLOAD = (1 << 4),
00588    AST_SOFTHANGUP_EXPLICIT =  (1 << 5),
00589    AST_SOFTHANGUP_UNBRIDGE =  (1 << 6),
00590 };

Enumerator:
AST_BRIDGE_COMPLETE 
AST_BRIDGE_FAILED 
AST_BRIDGE_FAILED_NOWARN 
AST_BRIDGE_RETRY 

Definition at line 136 of file channel.h.

00136                        {
00137    AST_BRIDGE_COMPLETE = 0,
00138    AST_BRIDGE_FAILED = -1,
00139    AST_BRIDGE_FAILED_NOWARN = -2,
00140    AST_BRIDGE_RETRY = -3,
00141 };

Enumerator:
AST_ADSI_UNKNOWN 
AST_ADSI_AVAILABLE 
AST_ADSI_UNAVAILABLE 
AST_ADSI_OFFHOOKONLY 

Definition at line 308 of file channel.h.

ast_channel states

Note:
Bits 0-15 of state are reserved for the state (up/down) of the line Bits 16-32 of state are reserved for flags
Enumerator:
AST_STATE_DOWN  Channel is down and available
AST_STATE_RESERVED  Channel is down, but reserved
AST_STATE_OFFHOOK  Channel is off hook
AST_STATE_DIALING  Digits (or equivalent) have been dialed
AST_STATE_RING  Line is ringing
AST_STATE_RINGING  Remote end is ringing
AST_STATE_UP  Line is up
AST_STATE_BUSY  Line is busy
AST_STATE_DIALING_OFFHOOK  Digits (or equivalent) have been dialed while offhook
AST_STATE_PRERING  Channel has detected an incoming call and is waiting for ring
AST_STATE_MUTE  Do not transmit voice data

Definition at line 321 of file channel.h.

00321                        {
00322    /*! Channel is down and available */
00323    AST_STATE_DOWN,
00324    /*! Channel is down, but reserved */
00325    AST_STATE_RESERVED,
00326    /*! Channel is off hook */
00327    AST_STATE_OFFHOOK,
00328    /*! Digits (or equivalent) have been dialed */
00329    AST_STATE_DIALING,
00330    /*! Line is ringing */
00331    AST_STATE_RING,
00332    /*! Remote end is ringing */
00333    AST_STATE_RINGING,
00334    /*! Line is up */
00335    AST_STATE_UP,
00336    /*! Line is busy */
00337    AST_STATE_BUSY,
00338    /*! Digits (or equivalent) have been dialed while offhook */
00339    AST_STATE_DIALING_OFFHOOK,
00340    /*! Channel has detected an incoming call and is waiting for ring */
00341    AST_STATE_PRERING,
00342 
00343    /*! Do not transmit voice data */
00344    AST_STATE_MUTE = (1 << 16),
00345 };

Channel reload reasons for manager events at load or reload of configuration.

Enumerator:
CHANNEL_MODULE_LOAD 
CHANNEL_MODULE_RELOAD 
CHANNEL_CLI_RELOAD 
CHANNEL_MANAGER_RELOAD 

Definition at line 594 of file channel.h.


Function Documentation

struct ast_channel* __ast_request_and_dial ( const char *  type,
int  format,
void *  data,
int  timeout,
int *  reason,
const char *  cidnum,
const char *  cidname,
struct outgoing_helper oh 
) [read]

Definition at line 2883 of file channel.c.

References __ast_request_and_dial_uniqueid().

Referenced by ast_request_and_dial(), and parkandannounce_exec().

02884 {
02885    return __ast_request_and_dial_uniqueid(type, format, data,
02886       timeout, outstate, 0, cid_num, cid_name, oh, NULL);
02887 }

struct ast_channel* __ast_request_and_dial_uniqueid ( const char *  type,
int  format,
void *  data,
int  timeout,
int *  reason,
int  callingpres,
const char *  cidnum,
const char *  cidname,
struct outgoing_helper oh,
char *  uniqueid 
) [read]

Definition at line 2889 of file channel.c.

References ast_channel::_state, outgoing_helper::account, ast_call(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_NO_ANSWER, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_inherit_variables(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, ast_frfree, ast_hangup(), ast_log(), ast_read(), ast_request_with_uniqueid(), ast_set_callerid(), ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), ast_channel::cdr, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, f, ast_frame::frametype, ast_channel::hangupcause, LOG_NOTICE, outgoing_helper::parent_channel, ast_channel::priority, outgoing_helper::priority, ast_frame::subclass, and outgoing_helper::vars.

Referenced by __ast_request_and_dial(), ast_pbx_outgoing_app_uniqueid(), ast_pbx_outgoing_exten_uniqueid(), and ast_request_and_dial_uniqueid().

02890 {
02891    int dummy_outstate;
02892    int cause = 0;
02893    struct ast_channel *chan;
02894    int res = 0;
02895    int last_subclass = 0;
02896    
02897    if (outstate)
02898       *outstate = 0;
02899    else
02900       outstate = &dummy_outstate;   /* make outstate always a valid pointer */
02901 
02902    chan = ast_request_with_uniqueid(type, format, data, &cause, uniqueid);
02903    if (!chan) {
02904       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
02905       /* compute error and return */
02906       if (cause == AST_CAUSE_BUSY)
02907          *outstate = AST_CONTROL_BUSY;
02908       else if (cause == AST_CAUSE_CONGESTION)
02909          *outstate = AST_CONTROL_CONGESTION;
02910       return NULL;
02911    }
02912 
02913    if (oh) {
02914       if (oh->vars)  
02915          ast_set_variables(chan, oh->vars);
02916       /* XXX why is this necessary, for the parent_channel perhaps ? */
02917       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
02918          ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
02919       if (oh->parent_channel)
02920          ast_channel_inherit_variables(oh->parent_channel, chan);
02921       if (oh->account)
02922          ast_cdr_setaccount(chan, oh->account); 
02923    }
02924    ast_set_callerid(chan, cid_num, cid_name, cid_num);
02925 
02926    
02927 
02928    if (!chan->cdr) { /* up till now, this insertion hasn't been done. Therefore,
02929             to keep from throwing off the basic order of the universe,
02930             we will try to keep this cdr from getting posted. */
02931       chan->cdr = ast_cdr_alloc();
02932       ast_cdr_init(chan->cdr, chan);
02933       ast_cdr_start(chan->cdr);
02934    }
02935    if (ast_call(chan, data, 0)) {   /* ast_call failed... */
02936       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
02937    } else {
02938       res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
02939       while (timeout && chan->_state != AST_STATE_UP) {
02940          struct ast_frame *f;
02941          res = ast_waitfor(chan, timeout);
02942          if (res <= 0) /* error, timeout, or done */
02943             break;
02944          if (timeout > -1)
02945             timeout = res;
02946          f = ast_read(chan);
02947          if (!f) {
02948             *outstate = AST_CONTROL_HANGUP;
02949             res = 0;
02950             break;
02951          }
02952          if (f->frametype == AST_FRAME_CONTROL) {
02953             switch (f->subclass) {
02954             case AST_CONTROL_RINGING:  /* record but keep going */
02955                *outstate = f->subclass;
02956                break;
02957 
02958             case AST_CONTROL_BUSY:
02959             case AST_CONTROL_CONGESTION:
02960             case AST_CONTROL_ANSWER:
02961                *outstate = f->subclass;
02962                timeout = 0;      /* trick to force exit from the while() */
02963                break;
02964 
02965             /* Ignore these */
02966             case AST_CONTROL_PROGRESS:
02967             case AST_CONTROL_PROCEEDING:
02968             case AST_CONTROL_HOLD:
02969             case AST_CONTROL_UNHOLD:
02970             case AST_CONTROL_VIDUPDATE:
02971             case AST_CONTROL_SRCUPDATE:
02972             case AST_CONTROL_SRCCHANGE:
02973             case -1:       /* Ignore -- just stopping indications */
02974                break;
02975 
02976             default:
02977                ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
02978             }
02979             last_subclass = f->subclass;
02980          }
02981          ast_frfree(f);
02982       }
02983    }
02984 
02985    /* Final fixups */
02986    if (oh) {
02987       if (!ast_strlen_zero(oh->context))
02988          ast_copy_string(chan->context, oh->context, sizeof(chan->context));
02989       if (!ast_strlen_zero(oh->exten))
02990          ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
02991       if (oh->priority) 
02992          chan->priority = oh->priority;
02993    }
02994    if (chan->_state == AST_STATE_UP)
02995       *outstate = AST_CONTROL_ANSWER;
02996 
02997    if (res <= 0) {
02998       if ( AST_CONTROL_RINGING == last_subclass ) 
02999          chan->hangupcause = AST_CAUSE_NO_ANSWER;
03000       if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
03001          ast_cdr_init(chan->cdr, chan);
03002       if (chan->cdr) {
03003          char tmp[256];
03004          snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
03005          ast_cdr_setapp(chan->cdr,"Dial",tmp);
03006          ast_cdr_update(chan);
03007          ast_cdr_start(chan->cdr);
03008          ast_cdr_end(chan->cdr);
03009          /* If the cause wasn't handled properly */
03010          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
03011             ast_cdr_failed(chan->cdr);
03012       }
03013       ast_hangup(chan);
03014       chan = NULL;
03015    }
03016    return chan;
03017 }

int ast_activate_generator ( struct ast_channel chan,
struct ast_generator gen,
void *  params 
)

Activate a given generator

Definition at line 1606 of file channel.c.

References ast_generator::alloc, ast_channel_lock, ast_channel_unlock, ast_prod(), ast_settimeout(), ast_channel::generator, generator_force(), ast_channel::generatordata, and ast_generator::release.

Referenced by app_exec(), ast_channel_start_silence_generator(), ast_linear_stream(), ast_playtones_start(), ast_tonepair_start(), channel_spy(), local_ast_moh_start(), old_milliwatt_exec(), and sms_exec().

01607 {
01608    int res = 0;
01609 
01610    ast_channel_lock(chan);
01611 
01612    if (chan->generatordata) {
01613       if (chan->generator && chan->generator->release)
01614          chan->generator->release(chan, chan->generatordata);
01615       chan->generatordata = NULL;
01616    }
01617 
01618    ast_prod(chan);
01619    if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
01620       res = -1;
01621    }
01622    
01623    if (!res) {
01624       ast_settimeout(chan, 160, generator_force, chan);
01625       chan->generator = gen;
01626    }
01627 
01628    ast_channel_unlock(chan);
01629 
01630    return res;
01631 }

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns number of active/allocated channels

Definition at line 444 of file channel.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and channels.

Referenced by quit_handler().

00445 {
00446    struct ast_channel *c;
00447    int cnt = 0;
00448    AST_LIST_LOCK(&channels);
00449    AST_LIST_TRAVERSE(&channels, c, chan_list)
00450       cnt++;
00451    AST_LIST_UNLOCK(&channels);
00452    return cnt;
00453 }

static int ast_add_fd ( struct pollfd pfd,
int  fd 
) [inline, static]

if fd is a valid descriptor, set *pfd with the descriptor

Returns:
Return 1 (not -1!) if added, 0 otherwise (so we can add the return value to the index into the array)

Definition at line 1322 of file channel.h.

References pollfd::events, pollfd::fd, POLLIN, and POLLPRI.

Referenced by ast_waitfor_nandfds().

01323 {
01324    pfd->fd = fd;
01325    pfd->events = POLLIN | POLLPRI;
01326    return fd >= 0;
01327 }

char* ast_alloc_uniqueid ( void   ) 

Create a uniqueid.

Definition at line 710 of file channel.c.

References ast_config_AST_SYSTEM_NAME, ast_mainpid, and malloc.

Referenced by action_originate().

00710                                {
00711    char *uniqueid;
00712    uniqueid = malloc(64);
00713    if (!uniqueid) return NULL;
00714    snprintf(uniqueid, 63, "%s-%d-%li.%d", ast_config_AST_SYSTEM_NAME, ast_mainpid, (long)time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
00715    return uniqueid;
00716 }

int ast_answer ( struct ast_channel chan  ) 

Answer a ringing call.

Parameters:
chan channel to answer This function answers a channel and handles all necessary call setup functions.
Returns:
Returns 0 on success, -1 on failure

Definition at line 1527 of file channel.c.

References ast_channel::_state, ast_channel_tech::answer, ast_cdr_answer(), ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, ast_channel::cdr, ast_channel::tech, and ast_channel::visible_indication.

Referenced by __login_exec(), action_bridge(), agi_exec_full(), alarmreceiver_exec(), app_exec(), ast_autoanswer_login(), ast_bridge_call(), ast_control_streamfile(), ast_pickup_call(), ast_retrieve_call(), auth_exec(), autoanswer_exec(), background_detect_exec(), bridge_exec(), builtin_parkcall(), common_exec(), conf_exec(), count_exec(), dictate_exec(), directory_exec(), disa_exec(), features_answer(), handle_answer(), ices_exec(), my_pickup_call(), my_pickup_channel(), old_milliwatt_exec(), park_call_exec(), park_exec(), pbx_builtin_answer(), pbx_builtin_background(), pbx_builtin_saycharacters(), pbx_builtin_saydigits(), pbx_builtin_saynumber(), pbx_builtin_sayphonetic(), pickup_do(), playback_exec(), privacy_exec(), read_exec(), record_exec(), rpt_exec(), run_station(), sayunixtime_exec(), send_waveform_to_channel(), skel_exec(), sla_handle_dial_state_event(), sla_station_exec(), sms_exec(), speech_background(), testclient_exec(), testserver_exec(), vm_exec(), vm_execmain(), waitforsilence_exec(), zapateller_exec(), and zapras_exec().

01528 {
01529    int res = 0;
01530    ast_channel_lock(chan);
01531    /* You can't answer an outbound call */
01532    if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
01533       ast_channel_unlock(chan);
01534       return 0;
01535    }
01536    /* Stop if we're a zombie or need a soft hangup */
01537    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01538       ast_channel_unlock(chan);
01539       return -1;
01540    }
01541    switch(chan->_state) {
01542    case AST_STATE_RINGING:
01543    case AST_STATE_RING:
01544       if (chan->tech->answer)
01545          res = chan->tech->answer(chan);
01546       ast_setstate(chan, AST_STATE_UP);
01547       ast_cdr_answer(chan->cdr);
01548       break;
01549    case AST_STATE_UP:
01550       ast_cdr_answer(chan->cdr);
01551       break;
01552    default:
01553       break;
01554    }
01555    chan->visible_indication = 0;
01556    ast_channel_unlock(chan);
01557    return res;
01558 }

int ast_autoservice_start ( struct ast_channel chan  ) 

Automatically service a channel for us...

Return values:
0 success
-1 failure, or the channel is already being autoserviced

Definition at line 186 of file autoservice.c.

References as_cond, ast_calloc, ast_channel_lock, ast_channel_unlock, ast_cond_signal(), AST_FLAG_END_DTMF_ONLY, AST_LIST_EMPTY, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_pthread_create_background, AST_PTHREADT_NULL, ast_set_flag, ast_test_flag, asthread, autoservice_run(), asent::chan, free, LOG_WARNING, asent::orig_end_dtmf_flag, and asent::use_count.

Referenced by _macro_exec(), acf_curl_exec(), acf_cut_exec(), acf_odbc_read(), acf_odbc_write(), array(), ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), ast_get_txt(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), builtin_blindtransfer(), conf_play(), feature_exec_app(), function_eval(), function_fieldqty(), function_realtime_read(), function_realtime_write(), osplookup_exec(), pbx_find_extension(), sla_station_exec(), smdi_msg_retrieve_read(), system_exec_helper(), and try_calling().

00187 {
00188    int res = 0;
00189    struct asent *as;
00190 
00191    /* Check if the channel already has autoservice */
00192    AST_LIST_LOCK(&aslist);
00193    AST_LIST_TRAVERSE(&aslist, as, list) {
00194       if (as->chan == chan) {
00195          as->use_count++;
00196          break;
00197       }
00198    }
00199    AST_LIST_UNLOCK(&aslist);
00200 
00201    if (as) {
00202       /* Entry exists, autoservice is already handling this channel */
00203       return 0;
00204    }
00205 
00206    if (!(as = ast_calloc(1, sizeof(*as))))
00207       return -1;
00208    
00209    /* New entry created */
00210    as->chan = chan;
00211    as->use_count = 1;
00212 
00213    ast_channel_lock(chan);
00214    as->orig_end_dtmf_flag = ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY) ? 1 : 0;
00215    if (!as->orig_end_dtmf_flag)
00216       ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
00217    ast_channel_unlock(chan);
00218 
00219    AST_LIST_LOCK(&aslist);
00220 
00221    if (AST_LIST_EMPTY(&aslist) && asthread != AST_PTHREADT_NULL) {
00222       ast_cond_signal(&as_cond);
00223    }
00224 
00225    AST_LIST_INSERT_HEAD(&aslist, as, list);
00226 
00227    if (asthread == AST_PTHREADT_NULL) { /* need start the thread */
00228       if (ast_pthread_create_background(&asthread, NULL, autoservice_run, NULL)) {
00229          ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n");
00230          /* There will only be a single member in the list at this point,
00231             the one we just added. */
00232          AST_LIST_REMOVE(&aslist, as, list);
00233          free(as);
00234          asthread = AST_PTHREADT_NULL;
00235          res = -1;
00236       } else {
00237          pthread_kill(asthread, SIGURG);
00238       }
00239    }
00240 
00241    AST_LIST_UNLOCK(&aslist);
00242 
00243    return res;
00244 }

int ast_autoservice_stop ( struct ast_channel chan  ) 

Stop servicing a channel for us...

Return values:
0 success
-1 error, or the channel has been hungup

Definition at line 246 of file autoservice.c.

References ast_channel::_softhangup, as_chan_list_state, ast_clear_flag, AST_FLAG_END_DTMF_ONLY, ast_frfree, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, AST_PTHREADT_NULL, ast_queue_frame(), asthread, asent::chan, f, free, asent::orig_end_dtmf_flag, and asent::use_count.

Referenced by _macro_exec(), acf_curl_exec(), acf_cut_exec(), acf_odbc_read(), acf_odbc_write(), array(), ast_dtmf_stream(), ast_get_enum(), ast_get_srv(), ast_get_txt(), ast_hangup(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), conf_play(), feature_exec_app(), finishup(), function_eval(), function_fieldqty(), function_realtime_read(), function_realtime_write(), osplookup_exec(), pbx_find_extension(), sla_station_exec(), smdi_msg_retrieve_read(), system_exec_helper(), and try_calling().

00247 {
00248    int res = -1;
00249    struct asent *as, *removed = NULL;
00250    struct ast_frame *f;
00251    int chan_list_state;
00252 
00253    AST_LIST_LOCK(&aslist);
00254 
00255    /* Save the autoservice channel list state.  We _must_ verify that the channel
00256     * list has been rebuilt before we return.  Because, after we return, the channel
00257     * could get destroyed and we don't want our poor autoservice thread to step on
00258     * it after its gone! */
00259    chan_list_state = as_chan_list_state;
00260 
00261    /* Find the entry, but do not free it because it still can be in the
00262       autoservice thread array */
00263    AST_LIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) {  
00264       if (as->chan == chan) {
00265          as->use_count--;
00266          if (as->use_count < 1) {
00267             AST_LIST_REMOVE_CURRENT(&aslist, list);
00268             removed = as;
00269          }
00270          break;
00271       }
00272    }
00273    AST_LIST_TRAVERSE_SAFE_END
00274 
00275    if (removed && asthread != AST_PTHREADT_NULL) {
00276       pthread_kill(asthread, SIGURG);
00277    }
00278 
00279    AST_LIST_UNLOCK(&aslist);
00280 
00281    if (!removed) {
00282       return 0;
00283    }
00284 
00285    /* Wait while autoservice thread rebuilds its list. */
00286    while (chan_list_state == as_chan_list_state) {
00287       usleep(1000);
00288    }
00289 
00290    /* Now autoservice thread should have no references to our entry
00291       and we can safely destroy it */
00292 
00293    if (!chan->_softhangup) {
00294       res = 0;
00295    }
00296 
00297    if (!as->orig_end_dtmf_flag) {
00298       ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
00299    }
00300 
00301    while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) {
00302       ast_queue_frame(chan, f);
00303       ast_frfree(f);
00304    }
00305 
00306    free(as);
00307 
00308    return res;
00309 }

void ast_begin_shutdown ( int  hangup  ) 

Initiate system shutdown.

Initiate system shutdown -- prevents new channels from being allocated. If "hangup" is non-zero, all existing channels will receive soft hangups

Definition at line 431 of file channel.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, and channels.

Referenced by quit_handler().

00432 {
00433    struct ast_channel *c;
00434    shutting_down = 1;
00435    if (hangup) {
00436       AST_LIST_LOCK(&channels);
00437       AST_LIST_TRAVERSE(&channels, c, chan_list)
00438          ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00439       AST_LIST_UNLOCK(&channels);
00440    }
00441 }

int ast_best_codec ( int  fmts  ) 

Pick the best audio codec.

Pick the best codec

Okay, ulaw is used by all telephony equipment, so start with it

Unless of course, you're a silly European, so then prefer ALAW

G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority

Okay, well, signed linear is easy to translate into other stuff

G.726 is standard ADPCM, in RFC3551 packing order

G.726 is standard ADPCM, in AAL2 packing order

ADPCM has great sound quality and is still pretty easy to translate

Okay, we're down to vocoders now, so pick GSM because it's small and easier to translate and sounds pretty good

iLBC is not too bad

Speex is free, but computationally more expensive than GSM

Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough to use it

G.729a is faster than 723 and slightly less expensive

Down to G.723.1 which is proprietary but at least designed for voice

Definition at line 656 of file channel.c.

References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_AUDIO_MASK, AST_FORMAT_G722, AST_FORMAT_G723_1, AST_FORMAT_G726, AST_FORMAT_G726_AAL2, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_ILBC, AST_FORMAT_LPC10, AST_FORMAT_SLINEAR, AST_FORMAT_SPEEX, AST_FORMAT_ULAW, ast_log(), LOG_WARNING, and prefs.

Referenced by __login_exec(), __oh323_new(), agent_call(), ast_codec_choose(), ast_iax2_new(), builtin_atxfer(), echo_exec(), findmeexec(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), local_new(), mgcp_new(), sip_new(), skinny_new(), socket_process(), and transmit_connect().

00657 {
00658    /* This just our opinion, expressed in code.  We are asked to choose
00659       the best codec to use, given no information */
00660    int x;
00661    static int prefs[] =
00662    {
00663       /*! Okay, ulaw is used by all telephony equipment, so start with it */
00664       AST_FORMAT_ULAW,
00665       /*! Unless of course, you're a silly European, so then prefer ALAW */
00666       AST_FORMAT_ALAW,
00667       /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */
00668       AST_FORMAT_G722,
00669       /*! Okay, well, signed linear is easy to translate into other stuff */
00670       AST_FORMAT_SLINEAR,
00671       /*! G.726 is standard ADPCM, in RFC3551 packing order */
00672       AST_FORMAT_G726,
00673       /*! G.726 is standard ADPCM, in AAL2 packing order */
00674       AST_FORMAT_G726_AAL2,
00675       /*! ADPCM has great sound quality and is still pretty easy to translate */
00676       AST_FORMAT_ADPCM,
00677       /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to
00678           translate and sounds pretty good */
00679       AST_FORMAT_GSM,
00680       /*! iLBC is not too bad */
00681       AST_FORMAT_ILBC,
00682       /*! Speex is free, but computationally more expensive than GSM */
00683       AST_FORMAT_SPEEX,
00684       /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
00685           to use it */
00686       AST_FORMAT_LPC10,
00687       /*! G.729a is faster than 723 and slightly less expensive */
00688       AST_FORMAT_G729A,
00689       /*! Down to G.723.1 which is proprietary but at least designed for voice */
00690       AST_FORMAT_G723_1,
00691    };
00692 
00693    /* Strip out video */
00694    fmts &= AST_FORMAT_AUDIO_MASK;
00695    
00696    /* Find the first preferred codec in the format given */
00697    for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++)
00698       if (fmts & prefs[x])
00699          return prefs[x];
00700    ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
00701    return 0;
00702 }

struct ast_channel* ast_bridged_channel ( struct ast_channel chan  )  [read]

int ast_call ( struct ast_channel chan,
char *  addr,
int  timeout 
)

Make a call.

Parameters:
chan which channel to make the call on
addr destination of the call
timeout time to wait on for connect Place a call, take no longer than timeout ms.
Returns:
Returns -1 on failure, 0 on not enough time (does not automatically stop ringing), and the number of seconds the connect took otherwise.

Definition at line 3084 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, ast_set_flag, ast_test_flag, ast_channel_tech::call, and ast_channel::tech.

Referenced by __ast_request_and_dial_uniqueid(), agent_call(), ast_feature_request_and_dial(), attempt_reconnect(), begin_dial(), connect_link(), features_call(), findmeexec(), ring_entry(), rpt(), rpt_exec(), and wait_for_answer().

03085 {
03086    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
03087       If the remote end does not answer within the timeout, then do NOT hang up, but
03088       return anyway.  */
03089    int res = -1;
03090    /* Stop if we're a zombie or need a soft hangup */
03091    ast_channel_lock(chan);
03092    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03093       if (chan->tech->call)
03094          res = chan->tech->call(chan, addr, timeout);
03095       ast_set_flag(chan, AST_FLAG_OUTGOING);
03096    }
03097    ast_channel_unlock(chan);
03098    return res;
03099 }

void ast_cancel_shutdown ( void   ) 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 456 of file channel.c.

Referenced by handle_abort_halt().

00457 {
00458    shutting_down = 0;
00459 }

const char* ast_cause2str ( int  state  ) 

Gives the string form of a given hangup cause.

Gives the string form of a given cause code

Parameters:
state cause to get the description of Give a name to a cause code Returns the text form of the binary cause code given

Definition at line 576 of file channel.c.

References causes, and ast_cause::desc.

Referenced by __transmit_response(), ast_do_masquerade(), ast_hangup(), findmeexec(), sip_hangup(), and transmit_request_with_auth().

00577 {
00578    int x;
00579 
00580    for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++) {
00581       if (causes[x].cause == cause)
00582          return causes[x].desc;
00583    }
00584 
00585    return "Unknown";
00586 }

void ast_change_name ( struct ast_channel chan,
char *  newname 
)

Change channel name.

Definition at line 3332 of file channel.c.

References ast_string_field_set, EVENT_FLAG_CALL, manager_event(), and name.

Referenced by update_name().

03333 {
03334    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
03335    ast_string_field_set(chan, name, newname);
03336 }

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,
const int  amaflag,
const char *  name_fmt,
  ... 
) [read]

Create a channel structure.

Returns:
Returns NULL on failure to allocate.
Note:
New channels are by default set to the "default" context and extension "s"

Definition at line 719 of file channel.c.

References ast_channel::_state, accountcode, ast_channel::alertpipe, ast_channel::amaflags, AST_ALERT_FD, ast_calloc, ast_cdr_alloc(), ast_cdr_init(), ast_cdr_start(), ast_config_AST_SYSTEM_NAME, ast_default_accountcode, ast_default_amaflags, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_UNLOCK, ast_log(), AST_MAX_FDS, ast_mutex_init(), ast_state2str(), ast_strdup, ast_string_field_build, ast_string_field_build_va, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), AST_TIMING_FD, ast_channel::cdr, channels, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, defaultlanguage, EVENT_FLAG_CALL, ast_channel::exten, ast_channel::fds, ast_channel::fin, ast_channel::flags, ast_channel::fout, free, HAVE_ZAPTEL, language, ast_channel::lock, LOG_WARNING, manager_event(), name, null_tech, ast_channel::priority, S_OR, ast_channel::sched, sched_context_create(), sched_context_destroy(), ast_channel::streamid, ast_channel::tech, ast_channel::timingfd, and ast_channel::varshead.

Referenced by __oh323_new(), acf_odbc_read(), acf_odbc_write(), action_bridge(), agent_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_masq_autoanswer_login(), ast_masq_hold_call(), ast_masq_park_call(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten_uniqueid(), bridge_exec(), builtin_atxfer(), check_goto_on_transfer(), features_new(), gtalk_new(), iax_park(), local_new(), make_email_file(), mgcp_new(), misdn_new(), nbs_new(), oss_new(), pbx_substitute_variables_helper_full(), phone_new(), sendpage(), sip_new(), sip_park(), skinny_new(), and zt_new().

00720 {
00721    struct ast_channel *tmp;
00722    int x;
00723    int flags;
00724    struct varshead *headp;
00725    va_list ap1, ap2;
00726 
00727    /* If shutting down, don't allocate any new channels */
00728    if (shutting_down) {
00729       ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
00730       return NULL;
00731    }
00732 
00733    if (!(tmp = ast_calloc(1, sizeof(*tmp))))
00734       return NULL;
00735 
00736    if (!(tmp->sched = sched_context_create())) {
00737       ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
00738       free(tmp);
00739       return NULL;
00740    }
00741    
00742    if ((ast_string_field_init(tmp, 128))) {
00743       sched_context_destroy(tmp->sched);
00744       free(tmp);
00745       return NULL;
00746    }
00747 
00748    /* Don't bother initializing the last two FD here, because they
00749       will *always* be set just a few lines down (AST_TIMING_FD,
00750       AST_ALERT_FD). */
00751    for (x = 0; x < AST_MAX_FDS - 2; x++)
00752       tmp->fds[x] = -1;
00753 
00754 #ifdef HAVE_ZAPTEL
00755    tmp->timingfd = open("/dev/zap/timer", O_RDWR);
00756    if (tmp->timingfd > -1) {
00757       /* Check if timing interface supports new
00758          ping/pong scheme */
00759       flags = 1;
00760       if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags))
00761          needqueue = 0;
00762    }
00763 #else
00764    tmp->timingfd = -1;              
00765 #endif               
00766 
00767    if (needqueue) {
00768       if (pipe(tmp->alertpipe)) {
00769          ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
00770 #ifdef HAVE_ZAPTEL
00771          if (tmp->timingfd > -1)
00772             close(tmp->timingfd);
00773 #endif
00774          sched_context_destroy(tmp->sched);
00775          ast_string_field_free_memory(tmp);
00776          free(tmp);
00777          return NULL;
00778       } else {
00779          flags = fcntl(tmp->alertpipe[0], F_GETFL);
00780          fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
00781          flags = fcntl(tmp->alertpipe[1], F_GETFL);
00782          fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
00783       }
00784    } else   /* Make sure we've got it done right if they don't */
00785       tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
00786 
00787    /* Always watch the alertpipe */
00788    tmp->fds[AST_ALERT_FD] = tmp->alertpipe[0];
00789    /* And timing pipe */
00790    tmp->fds[AST_TIMING_FD] = tmp->timingfd;
00791    ast_string_field_set(tmp, name, "**Unknown**");
00792 
00793    /* Initial state */
00794    tmp->_state = state;
00795 
00796    tmp->streamid = -1;
00797    
00798    tmp->fin = global_fin;
00799    tmp->fout = global_fout;
00800 
00801    if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
00802       ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL), 
00803          ast_atomic_fetchadd_int(&uniqueint, 1));
00804    } else {
00805       ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, 
00806          (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
00807    }
00808 
00809    tmp->cid.cid_name = ast_strdup(cid_name);
00810    tmp->cid.cid_num = ast_strdup(cid_num);
00811    
00812    if (!ast_strlen_zero(name_fmt)) {
00813       /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call.
00814        * And they all use slightly different formats for their name string.
00815        * This means, to set the name here, we have to accept variable args, and call the string_field_build from here.
00816        * This means, that the stringfields must have a routine that takes the va_lists directly, and 
00817        * uses them to build the string, instead of forming the va_lists internally from the vararg ... list.
00818        * This new function was written so this can be accomplished.
00819        */
00820       va_start(ap1, name_fmt);
00821       va_start(ap2, name_fmt);
00822       ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2);
00823       va_end(ap1);
00824       va_end(ap2);
00825    }
00826 
00827    /* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */
00828 
00829    /* These 4 variables need to be set up for the cdr_init() to work right */
00830    if (amaflag)
00831       tmp->amaflags = amaflag;
00832    else
00833       tmp->amaflags = ast_default_amaflags;
00834    
00835    if (!ast_strlen_zero(acctcode))
00836       ast_string_field_set(tmp, accountcode, acctcode);
00837    else
00838       ast_string_field_set(tmp, accountcode, ast_default_accountcode);
00839       
00840    if (!ast_strlen_zero(context))
00841       ast_copy_string(tmp->context, context, sizeof(tmp->context));
00842    else
00843       strcpy(tmp->context, "default");
00844 
00845    if (!ast_strlen_zero(exten))
00846       ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
00847    else
00848       strcpy(tmp->exten, "s");
00849 
00850    tmp->priority = 1;
00851       
00852    tmp->cdr = ast_cdr_alloc();
00853    ast_cdr_init(tmp->cdr, tmp);
00854    ast_cdr_start(tmp->cdr);
00855    
00856    headp = &tmp->varshead;
00857    AST_LIST_HEAD_INIT_NOLOCK(headp);
00858    
00859    ast_mutex_init(&tmp->lock);
00860    
00861    AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
00862    
00863    ast_string_field_set(tmp, language, defaultlanguage);
00864 
00865    tmp->tech = &null_tech;
00866 
00867    AST_LIST_LOCK(&channels);
00868    AST_LIST_INSERT_HEAD(&channels, tmp, chan_list);
00869    AST_LIST_UNLOCK(&channels);
00870 
00871    /*\!note
00872     * and now, since the channel structure is built, and has its name, let's
00873     * call the manager event generator with this Newchannel event. This is the
00874     * proper and correct place to make this call, but you sure do have to pass
00875     * a lot of data into this func to do it here!
00876     */
00877    if (!ast_strlen_zero(name_fmt)) {
00878       manager_event(EVENT_FLAG_CALL, "Newchannel",
00879             "Channel: %s\r\n"
00880             "State: %s\r\n"
00881             "CallerIDNum: %s\r\n"
00882             "CallerIDName: %s\r\n"
00883             "Uniqueid: %s\r\n",
00884             tmp->name, ast_state2str(state),
00885             S_OR(cid_num, "<unknown>"),
00886             S_OR(cid_name, "<unknown>"),
00887             tmp->uniqueid);
00888    }
00889 
00890    return tmp;
00891 }

int ast_channel_bridge ( struct ast_channel c0,
struct ast_channel c1,
struct ast_bridge_config config,
struct ast_frame **  fo,
struct ast_channel **  rc 
)

Bridge two channels together.

Bridge two channels together

Parameters:
c0 first channel to bridge
c1 second channel to bridge
config config for the channels
fo destination frame(?)
rc destination channel(?) Bridge two channels (c0 and c1) together. If an important frame occurs, we return that frame in rf (remember, it could be NULL) and which channel (0 or 1) in rc

Definition at line 3945 of file channel.c.

References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_FEATURE_PLAY_WARNING, AST_FEATURE_REDIRECT, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_generic_bridge(), ast_indicate(), ast_log(), ast_set_flag, AST_SOFTHANGUP_UNBRIDGE, ast_strlen_zero(), ast_test_flag, ast_tvadd(), ast_tvsub(), ast_verbose(), ast_channel::audiohooks, ast_channel_tech::bridge, bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, ast_bridge_config::end_sound, EVENT_FLAG_CALL, ast_bridge_config::feature_timer, ast_bridge_config::features_callee, ast_bridge_config::features_caller, ast_bridge_config::firstpass, ast_bridge_config::flags, ast_channel::generator, IS_DIGITAL, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::nativeformats, option_debug, option_verbose, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), ast_bridge_config::play_warning, ast_channel::readformat, ast_channel_tech::send_digit_begin, ast_bridge_config::start_sound, ast_bridge_config::start_time, t, ast_channel::tech, ast_bridge_config::timelimit, ast_channel::transfercapability, VERBOSE_PREFIX_3, ast_bridge_config::warning_freq, ast_bridge_config::warning_sound, and ast_channel::writeformat.

Referenced by ast_bridge_call().

03947 {
03948    struct ast_channel *who = NULL;
03949    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03950    int nativefailed=0;
03951    int firstpass;
03952    int o0nativeformats;
03953    int o1nativeformats;
03954    long time_left_ms=0;
03955    struct timeval nexteventts = { 0, };
03956    char caller_warning = 0;
03957    char callee_warning = 0;
03958 
03959    if (c0->_bridge) {
03960       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
03961          c0->name, c0->_bridge->name);
03962       return -1;
03963    }
03964    if (c1->_bridge) {
03965       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
03966          c1->name, c1->_bridge->name);
03967       return -1;
03968    }
03969 
03970    if (IS_DIGITAL(c0->transfercapability) || IS_DIGITAL(c1->transfercapability)) {
03971        config->flags = 0;
03972    }
03973    
03974    /* Stop if we're a zombie or need a soft hangup */
03975    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
03976        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
03977       return -1;
03978 
03979    *fo = NULL;
03980    firstpass = config->firstpass;
03981    config->firstpass = 0;
03982 
03983    if (ast_tvzero(config->start_time))
03984       config->start_time = ast_tvnow();
03985    time_left_ms = config->timelimit;
03986 
03987    caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
03988    callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
03989 
03990    if (config->start_sound && firstpass) {
03991       if (caller_warning)
03992          bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000);
03993       if (callee_warning)
03994          bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000);
03995    }
03996 
03997    /* Keep track of bridge */
03998    c0->_bridge = c1;
03999    c1->_bridge = c0;
04000 
04001    /* \todo  XXX here should check that cid_num is not NULL */
04002    manager_event(EVENT_FLAG_CALL, "Link",
04003             "Channel1: %s\r\n"
04004             "Channel2: %s\r\n"
04005             "Uniqueid1: %s\r\n"
04006             "Uniqueid2: %s\r\n"
04007             "CallerID1: %s\r\n"
04008             "CallerID2: %s\r\n",
04009             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04010 
04011    o0nativeformats = c0->nativeformats;
04012    o1nativeformats = c1->nativeformats;
04013 
04014    if (config->feature_timer) {
04015       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
04016    } else if (config->timelimit) {
04017       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
04018       if (caller_warning || callee_warning)
04019          nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000));
04020    }
04021 
04022    if (!c0->tech->send_digit_begin)
04023       ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
04024    if (!c1->tech->send_digit_begin)
04025       ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
04026 
04027    /* Before we enter in and bridge these two together tell them both the source of audio has changed */
04028    ast_indicate(c0, AST_CONTROL_SRCCHANGE);
04029    ast_indicate(c1, AST_CONTROL_SRCCHANGE);
04030 
04031    for (/* ever */;;) {
04032       struct timeval now = { 0, };
04033       int to;
04034 
04035       to = -1;
04036 
04037       if (!ast_tvzero(nexteventts)) {
04038          now = ast_tvnow();
04039          to = ast_tvdiff_ms(nexteventts, now);
04040          if (to <= 0) {
04041             if (!config->timelimit) {
04042                res = AST_BRIDGE_COMPLETE;
04043                break;
04044             }
04045             to = 0;
04046          }
04047       }
04048 
04049       if (config->timelimit) {
04050          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
04051          if (time_left_ms < to)
04052             to = time_left_ms;
04053 
04054          if (time_left_ms <= 0) {
04055             if (caller_warning && config->end_sound)
04056                bridge_playfile(c0, c1, config->end_sound, 0);
04057             if (callee_warning && config->end_sound)
04058                bridge_playfile(c1, c0, config->end_sound, 0);
04059             *fo = NULL;
04060             if (who)
04061                *rc = who;
04062             res = 0;
04063             break;
04064          }
04065          
04066          if (!to) {
04067             if (time_left_ms >= 5000 && config->warning_sound && config->play_warning) {
04068                int t = (time_left_ms + 500) / 1000; /* round to nearest second */
04069                if (caller_warning)
04070                   bridge_playfile(c0, c1, config->warning_sound, t);
04071                if (callee_warning)
04072                   bridge_playfile(c1, c0, config->warning_sound, t);
04073             }
04074             if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000)))
04075                nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
04076             else
04077                nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
04078          }
04079       }
04080 
04081       if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
04082          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04083             c0->_softhangup = 0;
04084          if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04085             c1->_softhangup = 0;
04086          c0->_bridge = c1;
04087          c1->_bridge = c0;
04088          if (option_debug)
04089             ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
04090          continue;
04091       }
04092       
04093       /* Stop if we're a zombie or need a soft hangup */
04094       if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
04095           ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
04096          *fo = NULL;
04097          if (who)
04098             *rc = who;
04099          res = 0;
04100          if (option_debug)
04101             ast_log(LOG_DEBUG, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
04102                c0->name, c1->name,
04103                ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
04104                ast_check_hangup(c0) ? "Yes" : "No",
04105                ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
04106                ast_check_hangup(c1) ? "Yes" : "No");
04107          break;
04108       }
04109       
04110       /* See if the BRIDGEPEER variable needs to be updated */
04111       if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER")))
04112          pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1->name);
04113       if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))
04114          pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
04115       
04116       if (c0->tech->bridge &&
04117           (config->timelimit == 0) &&
04118           (c0->tech->bridge == c1->tech->bridge) &&
04119           !nativefailed && !c0->monitor && !c1->monitor &&
04120           !c0->audiohooks && !c1->audiohooks && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) &&
04121           !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) &&
04122           !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
04123          /* Looks like they share a bridge method and nothing else is in the way */
04124          ast_set_flag(c0, AST_FLAG_NBRIDGE);
04125          ast_set_flag(c1, AST_FLAG_NBRIDGE);
04126          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
04127             /* \todo  XXX here should check that cid_num is not NULL */
04128             manager_event(EVENT_FLAG_CALL, "Unlink",
04129                      "Channel1: %s\r\n"
04130                      "Channel2: %s\r\n"
04131                      "Uniqueid1: %s\r\n"
04132                      "Uniqueid2: %s\r\n"
04133                      "CallerID1: %s\r\n"
04134                      "CallerID2: %s\r\n",
04135                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04136             if (option_debug)
04137                ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
04138 
04139             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
04140             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
04141 
04142             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04143                continue;
04144 
04145             c0->_bridge = NULL;
04146             c1->_bridge = NULL;
04147 
04148             return res;
04149          } else {
04150             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
04151             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
04152          }
04153          switch (res) {
04154          case AST_BRIDGE_RETRY:
04155             continue;
04156          default:
04157             if (option_verbose > 2)
04158                ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s ended\n",
04159                       c0->name, c1->name);
04160             /* fallthrough */
04161          case AST_BRIDGE_FAILED_NOWARN:
04162             nativefailed++;
04163             break;
04164          }
04165       }
04166    
04167       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
04168           (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
04169           !(c0->generator || c1->generator)) {
04170          if (ast_channel_make_compatible(c0, c1)) {
04171             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
04172             /* \todo  XXX here should check that cid_num is not NULL */
04173                                 manager_event(EVENT_FLAG_CALL, "Unlink",
04174                      "Channel1: %s\r\n"
04175                      "Channel2: %s\r\n"
04176                      "Uniqueid1: %s\r\n"
04177                      "Uniqueid2: %s\r\n"
04178                      "CallerID1: %s\r\n"
04179                      "CallerID2: %s\r\n",
04180                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04181             return AST_BRIDGE_FAILED;
04182          }
04183          o0nativeformats = c0->nativeformats;
04184          o1nativeformats = c1->nativeformats;
04185       }
04186       res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
04187       if (res != AST_BRIDGE_RETRY)
04188          break;
04189    }
04190 
04191    ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
04192    ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
04193 
04194    /* Now that we have broken the bridge the source will change yet again */
04195    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
04196    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
04197 
04198    c0->_bridge = NULL;
04199    c1->_bridge = NULL;
04200 
04201    /* \todo  XXX here should check that cid_num is not NULL */
04202    manager_event(EVENT_FLAG_CALL, "Unlink",
04203             "Channel1: %s\r\n"
04204             "Channel2: %s\r\n"
04205             "Uniqueid1: %s\r\n"
04206             "Uniqueid2: %s\r\n"
04207             "CallerID1: %s\r\n"
04208             "CallerID2: %s\r\n",
04209             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04210    if (option_debug)
04211       ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
04212 
04213    return res;
04214 }

int ast_channel_cmpwhentohangup ( struct ast_channel chan,
time_t  offset 
)

Compare a offset with the settings of when to hang a channel up.

Parameters:
chan channel on which to check for hang up
offset offset in seconds from current time
Returns:
1, 0, or -1 This function compares a offset from current time with the absolute time out on a channel (when to hang up). If the absolute time out on a channel is earlier than current time plus the offset, it returns 1, if the two time values are equal, it return 0, otherwise, it retturn -1.

Definition at line 476 of file channel.c.

References ast_channel::whentohangup.

00477 {
00478    time_t whentohangup;
00479 
00480    if (chan->whentohangup == 0) {
00481       return (offset == 0) ? 0 : -1;
00482    } else {
00483       if (offset == 0)  /* XXX why is this special ? */
00484          return (1);
00485       else {
00486          whentohangup = offset + time (NULL);
00487          if (chan->whentohangup < whentohangup)
00488             return (1);
00489          else if (chan->whentohangup == whentohangup)
00490             return (0);
00491          else
00492             return (-1);
00493       }
00494    }
00495 }

int ast_channel_datastore_add ( struct ast_channel chan,
struct ast_datastore datastore 
)

Add a datastore to a channel.

Definition at line 1345 of file channel.c.

References AST_LIST_INSERT_HEAD.

Referenced by setup_chanspy_ds(), smdi_msg_retrieve_read(), speech_create(), and try_calling().

01346 {
01347    int res = 0;
01348 
01349    AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
01350 
01351    return res;
01352 }

struct ast_datastore* ast_channel_datastore_alloc ( const struct ast_datastore_info info,
char *  uid 
) [read]

Create a channel datastore structure.

Definition at line 1284 of file channel.c.

References ast_calloc, ast_strdup, ast_datastore::info, and ast_datastore::uid.

Referenced by ast_channel_datastore_inherit(), setup_chanspy_ds(), smdi_msg_retrieve_read(), speech_create(), and try_calling().

01285 {
01286    struct ast_datastore *datastore = NULL;
01287 
01288    /* Make sure we at least have type so we can identify this */
01289    if (info == NULL) {
01290       return NULL;
01291    }
01292 
01293    /* Allocate memory for datastore and clear it */
01294    datastore = ast_calloc(1, sizeof(*datastore));
01295    if (datastore == NULL) {
01296       return NULL;
01297    }
01298 
01299    datastore->info = info;
01300 
01301    datastore->uid = ast_strdup(uid);
01302 
01303    return datastore;
01304 }

struct ast_datastore* ast_channel_datastore_find ( struct ast_channel chan,
const struct ast_datastore_info info,
char *  uid 
) [read]

Find a datastore on a channel.

Definition at line 1372 of file channel.c.

References AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_datastore::info, and ast_datastore::uid.

Referenced by chanspy_ds_free(), find_speech(), smdi_msg_read(), speech_background(), speech_destroy(), and try_calling().

01373 {
01374    struct ast_datastore *datastore = NULL;
01375    
01376    if (info == NULL)
01377       return NULL;
01378 
01379    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
01380       if (datastore->info == info) {
01381          if (uid != NULL && datastore->uid != NULL) {
01382             if (!strcasecmp(uid, datastore->uid)) {
01383                /* Matched by type AND uid */
01384                break;
01385             }
01386          } else {
01387             /* Matched by type at least */
01388             break;
01389          }
01390       }
01391    }
01392    AST_LIST_TRAVERSE_SAFE_END
01393 
01394    return datastore;
01395 }

int ast_channel_datastore_free ( struct ast_datastore datastore  ) 

Free a channel datastore structure.

Definition at line 1306 of file channel.c.

References ast_datastore::data, ast_datastore_info::destroy, free, ast_datastore::info, and ast_datastore::uid.

Referenced by ast_channel_free(), chanspy_ds_free(), and try_calling().

01307 {
01308    int res = 0;
01309 
01310    /* Using the destroy function (if present) destroy the data */
01311    if (datastore->info->destroy != NULL && datastore->data != NULL) {
01312       datastore->info->destroy(datastore->data);
01313       datastore->data = NULL;
01314    }
01315 
01316    /* Free allocated UID memory */
01317    if (datastore->uid != NULL) {
01318       free(datastore->uid);
01319       datastore->uid = NULL;
01320    }
01321 
01322    /* Finally free memory used by ourselves */
01323    free(datastore);
01324 
01325    return res;
01326 }

int ast_channel_datastore_inherit ( struct ast_channel from,
struct ast_channel to 
)

Inherit datastores from a parent to a child.

Definition at line 1328 of file channel.c.

References ast_channel_datastore_alloc(), AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_datastore_info::duplicate, ast_datastore::info, ast_datastore::inheritance, and ast_datastore::uid.

Referenced by local_call(), and wait_for_answer().

01329 {
01330    struct ast_datastore *datastore = NULL, *datastore2;
01331 
01332    AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
01333       if (datastore->inheritance > 0) {
01334          datastore2 = ast_channel_datastore_alloc(datastore->info, datastore->uid);
01335          if (datastore2) {
01336             datastore2->data = datastore->info->duplicate(datastore->data);
01337             datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
01338             AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
01339          }
01340       }
01341    }
01342    return 0;
01343 }

int ast_channel_datastore_remove ( struct ast_channel chan,
struct ast_datastore datastore 
)

Remove a datastore from a channel.

Definition at line 1354 of file channel.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, and AST_LIST_TRAVERSE_SAFE_END.

Referenced by chanspy_ds_free(), speech_background(), speech_destroy(), and try_calling().

01355 {
01356    struct ast_datastore *datastore2 = NULL;
01357    int res = -1;
01358 
01359    /* Find our position and remove ourselves */
01360    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, entry) {
01361       if (datastore2 == datastore) {
01362          AST_LIST_REMOVE_CURRENT(&chan->datastores, entry);
01363          res = 0;
01364          break;
01365       }
01366    }
01367    AST_LIST_TRAVERSE_SAFE_END
01368 
01369    return res;
01370 }

int ast_channel_defer_dtmf ( struct ast_channel chan  ) 

Set defer DTMF flag on channel.

Defers DTMF

Defer DTMF so that you only read things like hangups and audio. Returns non-zero if channel was already DTMF-deferred or 0 if channel is just now being DTMF-deferred

Definition at line 985 of file channel.c.

References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.

Referenced by __adsi_transmit_messages(), and find_cache().

00986 {
00987    int pre = 0;
00988 
00989    if (chan) {
00990       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
00991       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
00992    }
00993    return pre;
00994 }

void ast_channel_free ( struct ast_channel  ) 

Free a channel structure.

Definition at line 1197 of file channel.c.

References ast_channel::alertpipe, ast_app_group_discard(), ast_channel_datastore_free(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_unlock, ast_device_state_changed_literal(), ast_frfree, ast_jb_destroy(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_log(), ast_moh_cleanup(), ast_mutex_destroy(), ast_string_field_free_memory, ast_translator_free_path(), ast_var_delete(), channels, ast_channel::cid, f, free, free_cid(), ast_channel::lock, LOG_ERROR, LOG_WARNING, ast_channel::monitor, ast_channel::music_state, name, ast_channel::pbx, ast_channel::readtrans, ast_channel::sched, sched_context_destroy(), ast_channel_monitor::stop, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel::varshead, and ast_channel::writetrans.

Referenced by acf_odbc_read(), acf_odbc_write(), action_bridge(), agent_cleanup(), agent_new(), ast_do_masquerade(), ast_hangup(), ast_iax2_new(), ast_pbx_outgoing_cdr_failed(), gtalk_newcall(), local_new(), make_email_file(), pbx_substitute_variables_helper_full(), and sendpage().

01198 {
01199    int fd;
01200    struct ast_var_t *vardata;
01201    struct ast_frame *f;
01202    struct varshead *headp;
01203    struct ast_datastore *datastore = NULL;
01204    char name[AST_CHANNEL_NAME];
01205    
01206    headp=&chan->varshead;
01207    
01208    AST_LIST_LOCK(&channels);
01209    if (!AST_LIST_REMOVE(&channels, chan, chan_list)) {
01210       AST_LIST_UNLOCK(&channels);
01211       ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n");
01212    }
01213    /* Lock and unlock the channel just to be sure nobody has it locked still
01214       due to a reference retrieved from the channel list. */
01215    ast_channel_lock(chan);
01216    ast_channel_unlock(chan);
01217 
01218    /* Get rid of each of the data stores on the channel */
01219    while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
01220       /* Free the data store */
01221       ast_channel_datastore_free(datastore);
01222 
01223    /* Lock and unlock the channel just to be sure nobody has it locked still
01224       due to a reference that was stored in a datastore. (i.e. app_chanspy) */
01225    ast_channel_lock(chan);
01226    ast_channel_unlock(chan);
01227 
01228    if (chan->tech_pvt) {
01229       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
01230       free(chan->tech_pvt);
01231    }
01232 
01233    if (chan->sched)
01234       sched_context_destroy(chan->sched);
01235 
01236    ast_copy_string(name, chan->name, sizeof(name));
01237 
01238    /* Stop monitoring */
01239    if (chan->monitor)
01240       chan->monitor->stop( chan, 0 );
01241 
01242    /* If there is native format music-on-hold state, free it */
01243    if (chan->music_state)
01244       ast_moh_cleanup(chan);
01245 
01246    /* Free translators */
01247    if (chan->readtrans)
01248       ast_translator_free_path(chan->readtrans);
01249    if (chan->writetrans)
01250       ast_translator_free_path(chan->writetrans);
01251    if (chan->pbx)
01252       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
01253    free_cid(&chan->cid);
01254    /* Close pipes if appropriate */
01255    if ((fd = chan->alertpipe[0]) > -1)
01256       close(fd);
01257    if ((fd = chan->alertpipe[1]) > -1)
01258       close(fd);
01259    if ((fd = chan->timingfd) > -1)
01260       close(fd);
01261    while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
01262       ast_frfree(f);
01263    
01264    /* loop over the variables list, freeing all data and deleting list items */
01265    /* no need to lock the list, as the channel is already locked */
01266    
01267    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
01268       ast_var_delete(vardata);
01269 
01270    ast_app_group_discard(chan);
01271 
01272    /* Destroy the jitterbuffer */
01273    ast_jb_destroy(chan);
01274    
01275    ast_mutex_destroy(&chan->lock);
01276 
01277    ast_string_field_free_memory(chan);
01278    free(chan);
01279    AST_LIST_UNLOCK(&channels);
01280 
01281    ast_device_state_changed_literal(name, NULL, NULL);
01282 }

void ast_channel_inherit_variables ( const struct ast_channel parent,
struct ast_channel child 
)

Inherits channel variable from parent to child channel.

Parameters:
parent Parent channel
child Child channel
Scans all channel variables in the parent channel, looking for those that should be copied into the child channel. Variables whose names begin with a single '_' are copied into the child channel with the prefix removed. Variables whose names begin with '__' are copied into the child channel with their names unchanged.

Definition at line 3338 of file channel.c.

References AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_log(), ast_var_assign(), ast_var_full_name(), ast_var_name(), ast_var_value(), LOG_DEBUG, option_debug, and ast_channel::varshead.

Referenced by __ast_request_and_dial_uniqueid(), agent_call(), ast_feature_request_and_dial(), begin_dial(), findmeexec(), ring_entry(), and wait_for_answer().

03339 {
03340    struct ast_var_t *current, *newvar;
03341    const char *varname;
03342 
03343    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
03344       int vartype = 0;
03345 
03346       varname = ast_var_full_name(current);
03347       if (!varname)
03348          continue;
03349 
03350       if (varname[0] == '_') {
03351          vartype = 1;
03352          if (varname[1] == '_')
03353             vartype = 2;
03354       }
03355 
03356       switch (vartype) {
03357       case 1:
03358          newvar = ast_var_assign(&varname[1], ast_var_value(current));
03359          if (newvar) {
03360             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03361             if (option_debug)
03362                ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
03363          }
03364          break;
03365       case 2:
03366          newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
03367          if (newvar) {
03368             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03369             if (option_debug)
03370                ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
03371          }
03372          break;
03373       default:
03374          if (option_debug)
03375             ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
03376          break;
03377       }
03378    }
03379 }

int ast_channel_make_compatible ( struct ast_channel c0,
struct ast_channel c1 
)

Makes two channel formats compatible.

Parameters:
c0 first channel to make compatible
c1 other channel to make compatible Set two channels to compatible formats -- call before ast_channel_bridge in general .
Returns:
Returns 0 on success and -1 if it could not be done

Definition at line 3191 of file channel.c.

References AST_FORMAT_SLINEAR, ast_log(), ast_opt_transcode_via_slin, ast_set_read_format(), ast_set_write_format(), ast_translate_path_steps(), ast_translator_best_choice(), LOG_WARNING, ast_channel::nativeformats, ast_channel::readformat, and ast_channel::writeformat.

Referenced by action_bridge(), app_exec(), ast_channel_bridge(), ast_retrieve_call(), autoanswer_exec(), bridge_exec(), check_compat(), park_exec(), try_calling(), and wait_for_answer().

03192 {
03193    int src;
03194    int dst;
03195 
03196    if (chan->readformat == peer->writeformat && chan->writeformat == peer->readformat) {
03197       /* Already compatible!  Moving on ... */
03198       return 0;
03199    }
03200 
03201    /* Set up translation from the chan to the peer */
03202    src = chan->nativeformats;
03203    dst = peer->nativeformats;
03204    if (ast_translator_best_choice(&dst, &src) < 0) {
03205       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
03206       return -1;
03207    }
03208 
03209    /* if the best path is not 'pass through', then
03210       transcoding is needed; if desired, force transcode path
03211       to use SLINEAR between channels, but only if there is
03212       no direct conversion available */
03213    if ((src != dst) && ast_opt_transcode_via_slin &&
03214        (ast_translate_path_steps(dst, src) != 1))
03215       dst = AST_FORMAT_SLINEAR;
03216    if (ast_set_read_format(chan, dst) < 0) {
03217       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
03218       return -1;
03219    }
03220    if (ast_set_write_format(peer, dst) < 0) {
03221       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst);
03222       return -1;
03223    }
03224 
03225    /* Set up translation from the peer to the chan */
03226    src = peer->nativeformats;
03227    dst = chan->nativeformats;
03228    if (ast_translator_best_choice(&dst, &src) < 0) {
03229       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst);
03230       return -1;
03231    }
03232 
03233    /* if the best path is not 'pass through', then
03234       transcoding is needed; if desired, force transcode path
03235       to use SLINEAR between channels, but only if there is
03236       no direct conversion available */
03237    if ((src != dst) && ast_opt_transcode_via_slin &&
03238        (ast_translate_path_steps(dst, src) != 1))
03239       dst = AST_FORMAT_SLINEAR;
03240    if (ast_set_read_format(peer, dst) < 0) {
03241       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst);
03242       return -1;
03243    }
03244    if (ast_set_write_format(chan, dst) < 0) {
03245       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst);
03246       return -1;
03247    }
03248    return 0;
03249 }

int ast_channel_masquerade ( struct ast_channel original,
struct ast_channel clone 
)

Weird function made for call transfers.

Parameters:
original channel to make a copy of
clone copy of the original channel This is a very strange and freaky function used primarily for transfer. Suppose that "original" and "clone" are two channels in random situations. This function takes the guts out of "clone" and puts them into the "original" channel, then alerts the channel driver of the change, asking it to fixup any private information (like the p->owner pointer) that is affected by the change. The physical layer of the original channel is hung up.

Definition at line 3251 of file channel.c.

References ast_channel::_bridge, ast_bridged_channel(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_log(), ast_null_frame, ast_queue_frame(), ast_channel_tech::get_base_channel, LOG_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, option_debug, and ast_channel::tech.

Referenced by ast_async_goto(), ast_masq_autoanswer_login(), ast_masq_hold_call(), ast_masq_park_call(), ast_pickup_call(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), misdn_transfer_bc(), my_pickup_call(), my_pickup_channel(), pickup_do(), and sip_park().

03252 {
03253    int res = -1;
03254    struct ast_channel *final_orig, *final_clone, *base;
03255 
03256 retrymasq:
03257    final_orig = original;
03258    final_clone = clone;
03259 
03260    ast_channel_lock(original);
03261    while (ast_channel_trylock(clone)) {
03262       ast_channel_unlock(original);
03263       usleep(1);
03264       ast_channel_lock(original);
03265    }
03266 
03267    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
03268       and if so, we don't really want to masquerade it, but its proxy */
03269    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
03270       final_orig = original->_bridge;
03271 
03272    if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone))
03273       final_clone = clone->_bridge;
03274    
03275    if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) {
03276       final_clone = base;
03277    }
03278 
03279    if ((final_orig != original) || (final_clone != clone)) {
03280       /* Lots and lots of deadlock avoidance.  The main one we're competing with
03281        * is ast_write(), which locks channels recursively, when working with a
03282        * proxy channel. */
03283       if (ast_channel_trylock(final_orig)) {
03284          ast_channel_unlock(clone);
03285          ast_channel_unlock(original);
03286          goto retrymasq;
03287       }
03288       if (ast_channel_trylock(final_clone)) {
03289          ast_channel_unlock(final_orig);
03290          ast_channel_unlock(clone);
03291          ast_channel_unlock(original);
03292          goto retrymasq;
03293       }
03294       ast_channel_unlock(clone);
03295       ast_channel_unlock(original);
03296       original = final_orig;
03297       clone = final_clone;
03298    }
03299 
03300    if (original == clone) {
03301       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
03302       ast_channel_unlock(clone);
03303       ast_channel_unlock(original);
03304       return -1;
03305    }
03306 
03307    if (option_debug)
03308       ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
03309          clone->name, original->name);
03310    if (original->masq) {
03311       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03312          original->masq->name, original->name);
03313    } else if (clone->masqr) {
03314       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03315          clone->name, clone->masqr->name);
03316    } else {
03317       original->masq = clone;
03318       clone->masqr = original;
03319       ast_queue_frame(original, &ast_null_frame);
03320       ast_queue_frame(clone, &ast_null_frame);
03321       if (option_debug)
03322          ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
03323       res = 0;
03324    }
03325 
03326    ast_channel_unlock(clone);
03327    ast_channel_unlock(original);
03328 
03329    return res;
03330 }

struct ast_frame* ast_channel_queryoption ( struct ast_channel channel,
int  option,
void *  data,
int *  datalen,
int  block 
) [read]

Checks the value of an option

Query the value of an option, optionally blocking until a reply is received Works similarly to setoption except only reads the options.

char* ast_channel_reason2str ( int  reason  ) 

return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument

Parameters:
reason The integer argument, usually taken from AST_CONTROL_ macros
Returns:
char pointer explaining the code

Definition at line 2860 of file channel.c.

References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RING, and AST_CONTROL_RINGING.

Referenced by attempt_thread().

02861 {
02862    switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */
02863    {
02864    case 0:
02865       return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
02866    case AST_CONTROL_HANGUP:
02867       return "Hangup";
02868    case AST_CONTROL_RING:
02869       return "Local Ring";
02870    case AST_CONTROL_RINGING:
02871       return "Remote end Ringing";
02872    case AST_CONTROL_ANSWER:
02873       return "Remote end has Answered";
02874    case AST_CONTROL_BUSY:
02875       return "Remote end is Busy";
02876    case AST_CONTROL_CONGESTION:
02877       return "Congestion (circuits busy)";
02878    default:
02879       return "Unknown Reason!!";
02880    }
02881 }

int ast_channel_register ( const struct ast_channel_tech tech  ) 

Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.

Parameters:
tech Structure defining channel technology or "type"
Returns:
Returns 0 on success, -1 on failure.

Definition at line 498 of file channel.c.

References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_verbose(), channels, ast_channel_tech::description, LOG_DEBUG, LOG_WARNING, option_debug, option_verbose, chanlist::tech, ast_channel_tech::type, and VERBOSE_PREFIX_2.

Referenced by load_module(), and unload_module().

00499 {
00500    struct chanlist *chan;
00501 
00502    AST_LIST_LOCK(&channels);
00503 
00504    AST_LIST_TRAVERSE(&backends, chan, list) {
00505       if (!strcasecmp(tech->type, chan->tech->type)) {
00506          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00507          AST_LIST_UNLOCK(&channels);
00508          return -1;
00509       }
00510    }
00511    
00512    if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00513       AST_LIST_UNLOCK(&channels);
00514       return -1;
00515    }
00516    chan->tech = tech;
00517    AST_LIST_INSERT_HEAD(&backends, chan, list);
00518 
00519    if (option_debug)
00520       ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00521 
00522    if (option_verbose > 1)
00523       ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type,
00524              chan->tech->description);
00525 
00526    AST_LIST_UNLOCK(&channels);
00527    return 0;
00528 }

int ast_channel_sendhtml ( struct ast_channel channel,
int  subclass,
const char *  data,
int  datalen 
)

Sends HTML on given channel

Send HTML or URL on link. Returns 0 on success or -1 on failure

Definition at line 3179 of file channel.c.

References ast_channel_tech::send_html, and ast_channel::tech.

Referenced by agent_sendhtml(), ast_channel_sendurl(), and wait_for_answer().

03180 {
03181    if (chan->tech->send_html)
03182       return chan->tech->send_html(chan, subclass, data, datalen);
03183    return -1;
03184 }

int ast_channel_sendurl ( struct ast_channel channel,
const char *  url 
)

Sends a URL on a given link

Send URL on link. Returns 0 on success or -1 on failure

Definition at line 3186 of file channel.c.

References ast_channel_sendhtml(), and AST_HTML_URL.

Referenced by sendurl_exec(), and try_calling().

03187 {
03188    return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
03189 }

int ast_channel_setoption ( struct ast_channel channel,
int  option,
void *  data,
int  datalen,
int  block 
)

Sets an option on a channel.

Sets an option on a channel

Parameters:
channel channel to set options on
option option to change
data data specific to option
datalen length of the data
block blocking or not Set an option on a channel (see frame.h), optionally blocking awaiting the reply Returns 0 on success and -1 on failure

Definition at line 4217 of file channel.c.

References ast_log(), errno, LOG_ERROR, ast_channel_tech::setoption, and ast_channel::tech.

Referenced by ast_bridge_call(), common_exec(), conf_run(), func_channel_write(), handle_tddmode(), play_record_review(), reset_volumes(), rpt(), rpt_exec(), set_listen_volume(), set_talk_volume(), try_calling(), vm_forwardoptions(), and zt_hangup().

04218 {
04219    int res;
04220 
04221    if (chan->tech->setoption) {
04222       res = chan->tech->setoption(chan, option, data, datalen);
04223       if (res < 0)
04224          return res;
04225    } else {
04226       errno = ENOSYS;
04227       return -1;
04228    }
04229    if (block) {
04230       /* XXX Implement blocking -- just wait for our option frame reply, discarding
04231          intermediate packets. XXX */
04232       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
04233       return -1;
04234    }
04235    return 0;
04236 }

void ast_channel_setwhentohangup ( struct ast_channel chan,
time_t  offset 
)

Set when to hang a channel up.

Parameters:
chan channel on which to check for hang up
offset offset in seconds from current time of when to hang up This function sets the absolute time out on a channel (when to hang up).

Definition at line 468 of file channel.c.

References ast_null_frame, ast_queue_frame(), and ast_channel::whentohangup.

Referenced by action_timeout(), and timeout_write().

00469 {
00470    chan->whentohangup = offset ? time(NULL) + offset : 0;
00471    ast_queue_frame(chan, &ast_null_frame);
00472    return;
00473 }

struct ast_silence_generator* ast_channel_start_silence_generator ( struct ast_channel chan  )  [read]

Starts a silence generator on the given channel.

Parameters:
chan The channel to generate silence on
Returns:
An ast_silence_generator pointer, or NULL if an error occurs
This function will cause SLINEAR silence to be generated on the supplied channel until it is disabled; if the channel cannot be put into SLINEAR mode then the function will fail.

The pointer returned by this function must be preserved and passed to ast_channel_stop_silence_generator when you wish to stop the silence generation.

Definition at line 4545 of file channel.c.

References ast_activate_generator(), ast_calloc, AST_FORMAT_SLINEAR, ast_log(), ast_set_write_format(), free, LOG_DEBUG, LOG_ERROR, ast_silence_generator::old_write_format, option_debug, and ast_channel::writeformat.

Referenced by __ast_play_and_record(), ast_dtmf_stream(), channel_spy(), and record_exec().

04546 {
04547    struct ast_silence_generator *state;
04548 
04549    if (!(state = ast_calloc(1, sizeof(*state)))) {
04550       return NULL;
04551    }
04552 
04553    state->old_write_format = chan->writeformat;
04554 
04555    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
04556       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
04557       free(state);
04558       return NULL;
04559    }
04560 
04561    ast_activate_generator(chan, &silence_generator, state);
04562 
04563    if (option_debug)
04564       ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
04565 
04566    return state;
04567 }

void ast_channel_stop_silence_generator ( struct ast_channel chan,
struct ast_silence_generator state 
)

Stops a previously-started silence generator on the given channel.

Parameters:
chan The channel to operate on
state The ast_silence_generator pointer return by a previous call to ast_channel_start_silence_generator.
Returns:
nothing
This function will stop the operating silence generator and return the channel to its previous write format.

Definition at line 4569 of file channel.c.

References ast_deactivate_generator(), ast_log(), ast_set_write_format(), free, LOG_DEBUG, LOG_ERROR, ast_silence_generator::old_write_format, and option_debug.

Referenced by __ast_play_and_record(), ast_dtmf_stream(), channel_spy(), and record_exec().

04570 {
04571    if (!state)
04572       return;
04573 
04574    ast_deactivate_generator(chan);
04575 
04576    if (option_debug)
04577       ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
04578 
04579    if (ast_set_write_format(chan, state->old_write_format) < 0)
04580       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
04581 
04582    free(state);
04583 }

int ast_channel_supports_html ( struct ast_channel channel  ) 

Checks for HTML support on a channel

Returns 0 if channel does not support HTML or non-zero if it does

Definition at line 3174 of file channel.c.

References ast_channel_tech::send_html, and ast_channel::tech.

Referenced by sendurl_exec(), and try_calling().

03175 {
03176    return (chan->tech->send_html) ? 1 : 0;
03177 }

void ast_channel_undefer_dtmf ( struct ast_channel chan  ) 

Unset defer DTMF flag on channel.

Undeos a defer

Undo defer. ast_read will return any dtmf characters that were queued

Definition at line 997 of file channel.c.

References ast_clear_flag, and AST_FLAG_DEFER_DTMF.

Referenced by __adsi_transmit_messages(), find_cache(), and rpt_call().

00998 {
00999    if (chan)
01000       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
01001 }

void ast_channel_unregister ( const struct ast_channel_tech tech  ) 

Unregister a channel technology.

Parameters:
tech Structure defining channel technology or "type" that was previously registered
Returns:
No return value.

Definition at line 530 of file channel.c.

References AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, ast_log(), ast_verbose(), channels, free, LOG_DEBUG, option_debug, option_verbose, chanlist::tech, ast_channel_tech::type, and VERBOSE_PREFIX_2.

Referenced by __unload_module(), and unload_module().

00531 {
00532    struct chanlist *chan;
00533 
00534    if (option_debug)
00535       ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
00536 
00537    AST_LIST_LOCK(&channels);
00538 
00539    AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00540       if (chan->tech == tech) {
00541          AST_LIST_REMOVE_CURRENT(&backends, list);
00542          free(chan);
00543          if (option_verbose > 1)
00544             ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
00545          break;   
00546       }
00547    }
00548    AST_LIST_TRAVERSE_SAFE_END
00549 
00550    AST_LIST_UNLOCK(&channels);
00551 }

struct ast_channel* ast_channel_walk_locked ( const struct ast_channel prev  )  [read]

Browse channels in use Browse the channels currently in use.

Parameters:
prev where you want to start in the channel list
Returns:
Returns the next channel in the list, NULL on end. If it returns a channel, that channel *has been locked*!

Definition at line 1113 of file channel.c.

References channel_find_locked().

Referenced by action_status(), ast_complete_channels(), ast_pickup_call(), complete_ch_helper(), conf_exec(), handle_chanlist(), handle_chanlist_deprecated(), handle_core_set_debug_channel(), handle_debugchan_deprecated(), handle_nodebugchan_deprecated(), my_pickup_call(), my_pickup_channel(), next_channel(), pickup_by_exten(), pickup_by_mark(), and softhangup_exec().

01114 {
01115    return channel_find_locked(prev, NULL, 0, NULL, NULL, NULL);
01116 }

int ast_channel_whisper_feed ( struct ast_channel chan,
struct ast_frame f 
)

Feed an audio frame into the whisper buffer on a channel.

Parameters:
chan The channel to whisper onto
f The frame to to whisper onto chan
Returns:
0 for success, non-zero for failure

int ast_channel_whisper_start ( struct ast_channel chan  ) 

Begin 'whispering' onto a channel.

Parameters:
chan The channel to whisper onto
Returns:
0 for success, non-zero for failure
This function will add a whisper buffer onto a channel and set a flag causing writes to the channel to reduce the volume level of the written audio samples, and then to mix in audio from the whisper buffer if it is available.

Note: This function performs no locking; you must hold the channel's lock before calling this function.

void ast_channel_whisper_stop ( struct ast_channel chan  ) 

Stop 'whispering' onto a channel.

Parameters:
chan The channel to whisper onto
Returns:
0 for success, non-zero for failure
Note: This function performs no locking; you must hold the channel's lock before calling this function.

struct ast_variable* ast_channeltype_list ( void   )  [read]

return an ast_variable list of channeltypes

Definition at line 164 of file channel.c.

References AST_LIST_TRAVERSE, ast_variable_new(), ast_channel_tech::description, chanlist::tech, ast_channel_tech::type, and var.

00165 {
00166    struct chanlist *cl;
00167    struct ast_variable *var=NULL, *prev = NULL;
00168    AST_LIST_TRAVERSE(&backends, cl, list) {
00169       if (prev)  {
00170          if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description)))
00171             prev = prev->next;
00172       } else {
00173          var = ast_variable_new(cl->tech->type, cl->tech->description);
00174          prev = var;
00175       }
00176    }
00177    return var;
00178 }

int ast_check_hangup ( struct ast_channel chan  ) 

Check to see if a channel is needing hang up.

Parameters:
chan channel on which to check for hang up This function determines if the channel is being requested to be hung up.
Returns:
Returns 0 if not, or 1 if hang up is requested (including time-out).

Definition at line 386 of file channel.c.

References ast_channel::_softhangup, AST_SOFTHANGUP_TIMEOUT, ast_channel::tech_pvt, and ast_channel::whentohangup.

Referenced by __ast_read(), action_redirect(), app_exec(), ast_answer(), ast_bridge_call(), ast_bridge_call_thread(), ast_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_feature_request_and_dial(), ast_indicate_data(), ast_readstring_full(), ast_recvtext(), ast_rtp_bridge(), ast_sendmessage(), ast_sendtext(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), ast_write(), bridge_exec(), bridge_native_loop(), bridge_p2p_loop(), builtin_atxfer(), channel_spy(), common_exec(), conf_run(), deadagi_exec(), handle_request_invite(), handle_sendimage(), iax2_bridge(), pbx_exec(), rpt(), rpt_exec(), wait_for_answer(), zt_setoption(), and zt_tdd_sendtext().

00387 {
00388    if (chan->_softhangup)     /* yes if soft hangup flag set */
00389       return 1;
00390    if (!chan->tech_pvt)    /* yes if no technology private data */
00391       return 1;
00392    if (!chan->whentohangup)   /* no if no hangup scheduled */
00393       return 0;
00394    if (chan->whentohangup > time(NULL))   /* no if hangup time has not come yet. */
00395       return 0;
00396    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */
00397    return 1;
00398 }

void ast_deactivate_generator ( struct ast_channel chan  ) 

int ast_do_masquerade ( struct ast_channel original  ) 

Start masquerading a channel XXX This is a seriously wacked out operation. We're essentially putting the guts of the clone channel into the original channel. Start by killing off the original channel's backend. I'm not sure we're going to keep this function, because while the features are nice, the cost is very high in terms of pure nastiness. XXX.

Parameters:
chan Channel to masquerade
Start masquerading a channel XXX This is a seriously wacked out operation. We're essentially putting the guts of the clone channel into the original channel. Start by killing off the original channel's backend. I'm not sure we're going to keep this function, because while the features are nice, the cost is very high in terms of pure nastiness. XXX.

Note:
Assumes channel will be locked when called

Definition at line 3412 of file channel.c.

References ast_channel::_softhangup, ast_channel::_state, ast_channel::adsicpe, ast_channel::alertpipe, ast_app_group_update(), ast_bridged_channel(), ast_cause2str(), ast_channel_free(), ast_channel_lock, ast_channel_unlock, AST_CONTROL_SRCCHANGE, ast_copy_flags, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_ZOMBIE, AST_GENERATOR_FD, ast_indicate(), AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_NOLOCK, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_log(), AST_MAX_FDS, ast_null_frame, ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_string_field_set, ast_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::cdr, ast_datastore_info::chan_fixup, ast_channel::cid, clone_variables(), ast_datastore::data, EVENT_FLAG_CALL, ast_channel::fdno, ast_channel::fds, ast_channel_tech::fixup, free_translation(), ast_channel_tech::hangup, ast_channel::hangupcause, ast_datastore::info, language, ast_channel::lock, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, musicclass, name, ast_channel::nativeformats, option_debug, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, t, ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel_tech::type, ast_channel::visible_indication, and ast_channel::writeformat.

Referenced by __ast_read(), ast_async_goto(), ast_hangup(), ast_waitfor_nandfds(), ast_write(), do_bridge_masquerade(), iax_park(), sip_park(), and sip_park_thread().

03413 {
03414    int x,i;
03415    int res=0;
03416    int origstate;
03417    struct ast_frame *cur;
03418    const struct ast_channel_tech *t;
03419    void *t_pvt;
03420    struct ast_callerid tmpcid;
03421    struct ast_channel *clone = original->masq;
03422    struct ast_channel *bridged;
03423    struct ast_cdr *cdr;
03424    int rformat = original->readformat;
03425    int wformat = original->writeformat;
03426    char newn[100];
03427    char orig[100];
03428    char masqn[100];
03429    char zombn[100];
03430 
03431    if (option_debug > 3)
03432       ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
03433          clone->name, clone->_state, original->name, original->_state);
03434 
03435    /* XXX This is a seriously wacked out operation.  We're essentially putting the guts of
03436       the clone channel into the original channel.  Start by killing off the original
03437       channel's backend.   I'm not sure we're going to keep this function, because
03438       while the features are nice, the cost is very high in terms of pure nastiness. XXX */
03439 
03440    /* We need the clone's lock, too */
03441    ast_channel_lock(clone);
03442 
03443    if (option_debug > 1)
03444       ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock);
03445 
03446    /* Having remembered the original read/write formats, we turn off any translation on either
03447       one */
03448    free_translation(clone);
03449    free_translation(original);
03450 
03451 
03452    /* Unlink the masquerade */
03453    original->masq = NULL;
03454    clone->masqr = NULL;
03455    
03456    /* Save the original name */
03457    ast_copy_string(orig, original->name, sizeof(orig));
03458    /* Save the new name */
03459    ast_copy_string(newn, clone->name, sizeof(newn));
03460    /* Create the masq name */
03461    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
03462       
03463    /* Copy the name from the clone channel */
03464    ast_string_field_set(original, name, newn);
03465 
03466    /* Mangle the name of the clone channel */
03467    ast_string_field_set(clone, name, masqn);
03468    
03469    /* Notify any managers of the change, first the masq then the other */
03470    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
03471    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
03472 
03473    /* Swap the technologies */   
03474    t = original->tech;
03475    original->tech = clone->tech;
03476    clone->tech = t;
03477 
03478    /* Swap the cdrs */
03479    cdr = original->cdr;
03480    original->cdr = clone->cdr;
03481    clone->cdr = cdr;
03482 
03483    t_pvt = original->tech_pvt;
03484    original->tech_pvt = clone->tech_pvt;
03485    clone->tech_pvt = t_pvt;
03486 
03487    /* Swap the alertpipes */
03488    for (i = 0; i < 2; i++) {
03489       x = original->alertpipe[i];
03490       original->alertpipe[i] = clone->alertpipe[i];
03491       clone->alertpipe[i] = x;
03492    }
03493 
03494    /* 
03495     * Swap the readq's.  The end result should be this:
03496     *
03497     *  1) All frames should be on the new (original) channel.
03498     *  2) Any frames that were already on the new channel before this
03499     *     masquerade need to be at the end of the readq, after all of the
03500     *     frames on the old (clone) channel.
03501     *  3) The alertpipe needs to get poked for every frame that was already
03502     *     on the new channel, since we are now using the alert pipe from the
03503     *     old (clone) channel.
03504     */
03505    {
03506       AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
03507       AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
03508 
03509       AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
03510       AST_LIST_APPEND_LIST(&original->readq, &clone->readq, frame_list);
03511 
03512       while ((cur = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
03513          AST_LIST_INSERT_TAIL(&original->readq, cur, frame_list);
03514          if (original->alertpipe[1] > -1) {
03515             int poke = 0;
03516             write(original->alertpipe[1], &poke, sizeof(poke));
03517          }
03518       }
03519    }
03520 
03521    /* Swap the raw formats */
03522    x = original->rawreadformat;
03523    original->rawreadformat = clone->rawreadformat;
03524    clone->rawreadformat = x;
03525    x = original->rawwriteformat;
03526    original->rawwriteformat = clone->rawwriteformat;
03527    clone->rawwriteformat = x;
03528 
03529    clone->_softhangup = AST_SOFTHANGUP_DEV;
03530 
03531    /* And of course, so does our current state.  Note we need not
03532       call ast_setstate since the event manager doesn't really consider
03533       these separate.  We do this early so that the clone has the proper
03534       state of the original channel. */
03535    origstate = original->_state;
03536    original->_state = clone->_state;
03537    clone->_state = origstate;
03538 
03539    if (clone->tech->fixup){
03540       res = clone->tech->fixup(original, clone);
03541       if (res)
03542          ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
03543    }
03544 
03545    /* Start by disconnecting the original's physical side */
03546    if (clone->tech->hangup)
03547       res = clone->tech->hangup(clone);
03548    if (res) {
03549       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
03550       ast_channel_unlock(clone);
03551       return -1;
03552    }
03553    
03554    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
03555    /* Mangle the name of the clone channel */
03556    ast_string_field_set(clone, name, zombn);
03557    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid);
03558 
03559    /* Update the type. */
03560    t_pvt = original->monitor;
03561    original->monitor = clone->monitor;
03562    clone->monitor = t_pvt;
03563    
03564    /* Keep the same language.  */
03565    ast_string_field_set(original, language, clone->language);
03566    /* Copy the FD's other than the generator fd */
03567    for (x = 0; x < AST_MAX_FDS; x++) {
03568       if (x != AST_GENERATOR_FD)
03569          original->fds[x] = clone->fds[x];
03570    }
03571 
03572    ast_app_group_update(clone, original);
03573    /* Move data stores over */
03574    if (AST_LIST_FIRST(&clone->datastores)) {
03575       struct ast_datastore *ds;
03576       AST_LIST_APPEND_LIST(&original->datastores, &clone->datastores, entry);
03577       AST_LIST_TRAVERSE(&original->datastores, ds, entry) {
03578          if (ds->info->chan_fixup)
03579             ds->info->chan_fixup(ds->data, clone, original);
03580       }
03581    }
03582 
03583    clone_variables(original, clone);
03584    /* Presense of ADSI capable CPE follows clone */
03585    original->adsicpe = clone->adsicpe;
03586    /* Bridge remains the same */
03587    /* CDR fields remain the same */
03588    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
03589    /* Application and data remain the same */
03590    /* Clone exception  becomes real one, as with fdno */
03591    ast_copy_flags(original, clone, AST_FLAG_EXCEPTION);
03592    original->fdno = clone->fdno;
03593    /* Schedule context remains the same */
03594    /* Stream stuff stays the same */
03595    /* Keep the original state.  The fixup code will need to work with it most likely */
03596 
03597    /* Just swap the whole structures, nevermind the allocations, they'll work themselves
03598       out. */
03599    tmpcid = original->cid;
03600    original->cid = clone->cid;
03601    clone->cid = tmpcid;
03602    
03603    /* Restore original timing file descriptor */
03604    original->fds[AST_TIMING_FD] = original->timingfd;
03605    
03606    /* Our native formats are different now */
03607    original->nativeformats = clone->nativeformats;
03608    
03609    /* Context, extension, priority, app data, jump table,  remain the same */
03610    /* pvt switches.  pbx stays the same, as does next */
03611    
03612    /* Set the write format */
03613    ast_set_write_format(original, wformat);
03614 
03615    /* Set the read format */
03616    ast_set_read_format(original, rformat);
03617 
03618    /* Copy the music class */
03619    ast_string_field_set(original, musicclass, clone->musicclass);
03620 
03621    if (option_debug)
03622       ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
03623 
03624    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
03625       can fix up everything as best as possible */
03626    if (original->tech->fixup) {
03627       res = original->tech->fixup(clone, original);
03628       if (res) {
03629          ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
03630             original->tech->type, original->name);
03631          ast_channel_unlock(clone);
03632          return -1;
03633       }
03634    } else
03635       ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
03636          original->tech->type, original->name);
03637 
03638    /* If an indication is currently playing maintain it on the channel that is taking the place of original */
03639    if (original->visible_indication)
03640       ast_indicate(original, original->visible_indication);
03641    
03642    /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
03643       a zombie so nothing tries to touch it.  If it's already been marked as a
03644       zombie, then free it now (since it already is considered invalid). */
03645    if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) {
03646       if (option_debug)
03647          ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name);
03648       ast_channel_unlock(clone);
03649       manager_event(EVENT_FLAG_CALL, "Hangup",
03650          "Channel: %s\r\n"
03651          "Uniqueid: %s\r\n"
03652          "Cause: %d\r\n"
03653          "Cause-txt: %s\r\n",
03654          clone->name,
03655          clone->uniqueid,
03656          clone->hangupcause,
03657          ast_cause2str(clone->hangupcause)
03658          );
03659       ast_channel_free(clone);
03660    } else {
03661       if (option_debug)
03662          ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
03663       ast_set_flag(clone, AST_FLAG_ZOMBIE);
03664       ast_queue_frame(clone, &ast_null_frame);
03665       ast_channel_unlock(clone);
03666    }
03667    
03668    /* Signal any blocker */
03669    if (ast_test_flag(original, AST_FLAG_BLOCKING))
03670       pthread_kill(original->blocker, SIGURG);
03671    if (option_debug)
03672       ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state);
03673 
03674    if ((bridged = ast_bridged_channel(original))) {
03675       ast_channel_lock(bridged);
03676       ast_indicate(bridged, AST_CONTROL_SRCCHANGE);
03677       ast_channel_unlock(bridged);
03678    }
03679 
03680    ast_indicate(original, AST_CONTROL_SRCCHANGE);
03681 
03682    return 0;
03683 }

static int ast_fdisset ( struct pollfd pfds,
int  fd,
int  max,
int *  start 
) [inline, static]

Helper function for migrating select to poll.

Definition at line 1330 of file channel.h.

References pollfd::revents.

Referenced by do_monitor().

01331 {
01332    int x;
01333    int dummy=0;
01334 
01335    if (fd < 0)
01336       return 0;
01337    if (!start)
01338       start = &dummy;
01339    for (x = *start; x<max; x++)
01340       if (pfds[x].fd == fd) {
01341          if (x == *start)
01342             (*start)++;
01343          return pfds[x].revents;
01344       }
01345    return 0;
01346 }

struct ast_channel* ast_get_channel_by_exten_locked ( const char *  exten,
const char *  context 
) [read]

Get channel by exten (and optionally context) and lock it.

Definition at line 1138 of file channel.c.

References channel_find_locked().

01139 {
01140    return channel_find_locked(NULL, NULL, 0, context, exten, NULL);
01141 }

struct ast_channel* ast_get_channel_by_name_locked ( const char *  name  )  [read]

struct ast_channel* ast_get_channel_by_name_prefix_locked ( const char *  name,
const int  namelen 
) [read]

Get channel by name prefix (locks channel).

Definition at line 1125 of file channel.c.

References channel_find_locked().

Referenced by action_bridge(), ast_parse_device_state(), bridge_exec(), common_exec(), and mixmonitor_cli().

01126 {
01127    return channel_find_locked(NULL, name, namelen, NULL, NULL, NULL);
01128 }

struct ast_channel* ast_get_channel_by_uniqueid_locked ( const char *  uniqueid  )  [read]

Get channel by uniqueid (locks channel)

Definition at line 1150 of file channel.c.

References channel_find_locked().

Referenced by action_hangup(), action_redirect(), ast_get_holded_call(), next_channel(), start_monitor_action(), and stop_monitor_action().

01151 {
01152    return channel_find_locked(NULL, NULL, 0, NULL, NULL, uniqueid);
01153 }

struct ast_channel_tech* ast_get_channel_tech ( const char *  name  )  [read]

Get a channel technology structure by name.

Parameters:
name name of technology to find
Returns:
a pointer to the structure, or NULL if no matching technology found

Definition at line 553 of file channel.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), channels, LOG_WARNING, chanlist::tech, and ast_channel_tech::type.

Referenced by ast_device_state().

00554 {
00555    struct chanlist *chanls;
00556    const struct ast_channel_tech *ret = NULL;
00557 
00558    if (AST_LIST_LOCK(&channels)) {
00559       ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
00560       return NULL;
00561    }
00562 
00563    AST_LIST_TRAVERSE(&backends, chanls, list) {
00564       if (!strcasecmp(name, chanls->tech->type)) {
00565          ret = chanls->tech;
00566          break;
00567       }
00568    }
00569 
00570    AST_LIST_UNLOCK(&channels);
00571    
00572    return ret;
00573 }

ast_group_t ast_get_group ( const char *  s  ) 

Definition at line 4390 of file channel.c.

References ast_log(), ast_strdupa, ast_strlen_zero(), group, LOG_ERROR, LOG_WARNING, and strsep().

Referenced by _parse(), build_device(), build_gateway(), build_peer(), build_user(), func_channel_write(), pickdown_exec(), pickup_exec(), process_zap(), read_agent_config(), and steal_exec().

04391 {
04392    char *piece;
04393    char *c;
04394    int start=0, finish=0, x;
04395    ast_group_t group = 0;
04396 
04397    if (ast_strlen_zero(s))
04398       return 0;
04399 
04400    c = ast_strdupa(s);
04401    
04402    while ((piece = strsep(&c, ","))) {
04403       if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
04404          /* Range */
04405       } else if (sscanf(piece, "%d", &start)) {
04406          /* Just one */
04407          finish = start;
04408       } else {
04409          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
04410          continue;
04411       }
04412       for (x = start; x <= finish; x++) {
04413          if ((x > 63) || (x < 0)) {
04414             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
04415          } else
04416             group |= ((ast_group_t) 1 << x);
04417       }
04418    }
04419    return group;
04420 }

int ast_hangup ( struct ast_channel chan  ) 

Hang up a channel.

Note:
This function performs a hard hangup on a channel. Unlike the soft-hangup, this function performs all stream stopping, etc, on the channel that needs to end. chan is no longer valid after this call.
Parameters:
chan channel to hang up
Returns:
Returns 0 on success, -1 on failure.

Definition at line 1434 of file channel.c.

References ast_assert, ast_audiohook_detach_list(), ast_autoservice_stop(), ast_cause2str(), ast_cdr_detach(), ast_cdr_end(), ast_channel_free(), ast_channel_lock, ast_channel_unlock, ast_closestream(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_set_flag, ast_test_flag, ast_channel::audiohooks, ast_channel::blocker, ast_channel::blockproc, ast_channel::cdr, EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::masq, ast_channel::masqr, option_debug, ast_generator::release, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::tech, and ast_channel::vstream.

Referenced by __ast_pbx_run(), __ast_request_and_dial_uniqueid(), __oh323_new(), action_bridge(), agent_hangup(), agent_read(), alsa_new(), answer_exec_run(), app_exec(), ast_async_goto(), ast_autoanswer_login(), ast_bridge_call_thread(), ast_dial_destroy(), ast_dial_hangup(), ast_feature_request_and_dial(), ast_iax2_new(), ast_pbx_outgoing_app_uniqueid(), ast_pbx_outgoing_exten_uniqueid(), ast_pbx_run_app(), ast_retrieve_call(), ast_retrieve_call_to_death(), ast_send_message(), async_wait(), autoanswer_exec(), begin_dial(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_free(), conf_run(), connect_link(), do_autoanswer_thread(), do_hang(), do_holding_thread(), do_parking_thread(), features_hangup(), findmeexec(), gtalk_new(), handle_enbloc_call_message(), handle_frame(), handle_frame_ownerless(), handle_hd_hf(), handle_init_event(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_soft_key_event_message(), handle_stimulus_message(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), local_attended_transfer(), local_hangup(), mgcp_new(), mgcp_ss(), monitor_dial(), nbs_new(), oss_new(), park_exec(), parkandannounce_exec(), phone_new(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss_thread(), try_calling(), wait_for_answer(), wait_for_winner(), zt_handle_event(), and zt_new().

01435 {
01436    int res = 0;
01437    struct ast_cdr *cdr = NULL;
01438 
01439    /* Don't actually hang up a channel that will masquerade as someone else, or
01440       if someone is going to masquerade as us */
01441    ast_channel_lock(chan);
01442 
01443    if (chan->audiohooks) {
01444       ast_audiohook_detach_list(chan->audiohooks);
01445       chan->audiohooks = NULL;
01446    }
01447 
01448    ast_autoservice_stop(chan);
01449 
01450    if (chan->masq) {
01451       if (ast_do_masquerade(chan))
01452          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01453    }
01454 
01455    if (chan->masq) {
01456       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
01457       ast_channel_unlock(chan);
01458       return 0;
01459    }
01460    /* If this channel is one which will be masqueraded into something,
01461       mark it as a zombie already, so we know to free it later */
01462    if (chan->masqr) {
01463       ast_set_flag(chan, AST_FLAG_ZOMBIE);
01464       ast_channel_unlock(chan);
01465       return 0;
01466    }
01467    free_translation(chan);
01468    /* Close audio stream */
01469    if (chan->stream) {
01470       ast_closestream(chan->stream);
01471       chan->stream = NULL;
01472    }
01473    /* Close video stream */
01474    if (chan->vstream) {
01475       ast_closestream(chan->vstream);
01476       chan->vstream = NULL;
01477    }
01478    if (chan->sched) {
01479       sched_context_destroy(chan->sched);
01480       chan->sched = NULL;
01481    }
01482    
01483    if (chan->generatordata)   /* Clear any tone stuff remaining */
01484       chan->generator->release(chan, chan->generatordata);
01485    chan->generatordata = NULL;
01486    chan->generator = NULL;
01487    if (chan->cdr) {     /* End the CDR if it hasn't already */
01488       ast_cdr_end(chan->cdr);
01489       cdr = chan->cdr;
01490       chan->cdr = NULL;
01491    }
01492    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01493       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
01494                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
01495                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
01496       ast_assert(0);
01497    }
01498    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
01499       if (option_debug)
01500          ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
01501       if (chan->tech->hangup)
01502          res = chan->tech->hangup(chan);
01503    } else {
01504       if (option_debug)
01505          ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
01506    }
01507          
01508    ast_channel_unlock(chan);
01509    manager_event(EVENT_FLAG_CALL, "Hangup",
01510          "Channel: %s\r\n"
01511          "Uniqueid: %s\r\n"
01512          "Cause: %d\r\n"
01513          "Cause-txt: %s\r\n",
01514          chan->name,
01515          chan->uniqueid,
01516          chan->hangupcause,
01517          ast_cause2str(chan->hangupcause)
01518          );
01519    ast_channel_free(chan);
01520 
01521    if (cdr)
01522       ast_cdr_detach(cdr);
01523 
01524    return res;
01525 }

int ast_indicate ( struct ast_channel chan,
int  condition 
)

Indicates condition of channel.

Note:
Indicate a condition such as AST_CONTROL_BUSY, AST_CONTROL_RINGING, or AST_CONTROL_CONGESTION on a channel
Parameters:
chan channel to change the indication
condition which condition to indicate on the channel
Returns:
Returns 0 on success, -1 on failure

Definition at line 2374 of file channel.c.

References ast_indicate_data().

Referenced by __ast_play_and_record(), agent_new(), ast_bridge_call(), ast_channel_bridge(), ast_do_masquerade(), ast_dtmf_stream(), ast_feature_request_and_dial(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), conf_run(), disa_exec(), do_parking_thread(), features_indicate(), finishup(), function_remote(), handle_frame(), handle_recordfile(), mgcp_ss(), monitor_dial(), park_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), record_exec(), rpt(), rpt_exec(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), sla_trunk_exec(), and wait_for_answer().

02375 {
02376    return ast_indicate_data(chan, condition, NULL, 0);
02377 }

int ast_indicate_data ( struct ast_channel chan,
int  condition,
const void *  data,
size_t  datalen 
)

Indicates condition of channel, with payload.

Note:
Indicate a condition such as AST_CONTROL_BUSY, AST_CONTROL_RINGING, or AST_CONTROL_CONGESTION on a channel
Parameters:
chan channel to change the indication
condition which condition to indicate on the channel
data pointer to payload data
datalen size of payload data
Returns:
Returns 0 on success, -1 on failure

Definition at line 2379 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FLAG_ZOMBIE, ast_get_indication_tone(), ast_log(), ast_playtones_start(), ast_playtones_stop(), ast_test_flag, tone_zone_sound::data, ast_channel_tech::indicate, LOG_DEBUG, LOG_WARNING, option_debug, ast_channel::tech, ast_channel::visible_indication, and ast_channel::zone.

Referenced by __login_exec(), agent_hangup(), ast_bridge_call(), ast_generic_bridge(), ast_indicate(), bridge_native_loop(), bridge_p2p_loop(), do_parking_thread(), park_call_full(), pbx_builtin_waitexten(), and wait_for_answer().

02380 {
02381    int res = -1;
02382 
02383    ast_channel_lock(chan);
02384    /* Stop if we're a zombie or need a soft hangup */
02385    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02386       ast_channel_unlock(chan);
02387       return -1;
02388    }
02389    if (chan->tech->indicate)
02390       res = chan->tech->indicate(chan, condition, data, datalen);
02391    ast_channel_unlock(chan);
02392    if (!chan->tech->indicate || res) {
02393       /*
02394        * Device does not support (that) indication, lets fake
02395        * it by doing our own tone generation. (PM2002)
02396        */
02397       if (condition < 0)
02398          ast_playtones_stop(chan);
02399       else {
02400          const struct tone_zone_sound *ts = NULL;
02401          switch (condition) {
02402          case AST_CONTROL_RINGING:
02403             ts = ast_get_indication_tone(chan->zone, "ring");
02404             break;
02405          case AST_CONTROL_BUSY:
02406             ts = ast_get_indication_tone(chan->zone, "busy");
02407             break;
02408          case AST_CONTROL_CONGESTION:
02409             ts = ast_get_indication_tone(chan->zone, "congestion");
02410             break;
02411          }
02412          if (ts && ts->data[0]) {
02413             if (option_debug)
02414                ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
02415             ast_playtones_start(chan,0,ts->data, 1);
02416             res = 0;
02417             chan->visible_indication = condition;
02418          } else if (condition == AST_CONTROL_PROGRESS) {
02419             /* ast_playtones_stop(chan); */
02420          } else if (condition == AST_CONTROL_PROCEEDING) {
02421             /* Do nothing, really */
02422          } else if (condition == AST_CONTROL_HOLD) {
02423             /* Do nothing.... */
02424          } else if (condition == AST_CONTROL_UNHOLD) {
02425             /* Do nothing.... */
02426          } else if (condition == AST_CONTROL_VIDUPDATE) {
02427             /* Do nothing.... */
02428          } else if (condition == AST_CONTROL_SRCUPDATE) {
02429             /* Do nothing... */
02430          } else if (condition == AST_CONTROL_SRCCHANGE) {
02431             /* Do nothing... */
02432          } else {
02433             /* not handled */
02434             ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
02435             res = -1;
02436          }
02437       }
02438    } else
02439       chan->visible_indication = condition;
02440 
02441    return res;
02442 }

int ast_internal_timing_enabled ( struct ast_channel chan  ) 

Check if the channel can run in internal timing mode.

Parameters:
chan The channel to check
Returns:
boolean
This function will return 1 if internal timing is enabled and the timing device is available.

Definition at line 2356 of file channel.c.

References ast_log(), ast_opt_internal_timing, LOG_DEBUG, option_debug, and ast_channel::timingfd.

Referenced by add_sdp(), and ast_read_generator_actions().

02357 {
02358    int ret = ast_opt_internal_timing && chan->timingfd > -1;
02359    if (option_debug > 4)
02360       ast_log(LOG_DEBUG, "Internal timing is %s (option_internal_timing=%d chan->timingfd=%d)\n", ret? "enabled": "disabled", ast_opt_internal_timing, chan->timingfd);
02361    return ret;
02362 }

char* ast_print_group ( char *  buf,
int  buflen,
ast_group_t  group 
)

print call- and pickup groups into buffer

Definition at line 4475 of file channel.c.

Referenced by _sip_show_peer(), func_channel_read(), misdn_cfg_get_config_string(), print_group(), read_config(), and serialize_showchan().

04476 {
04477    unsigned int i;
04478    int first=1;
04479    char num[3];
04480 
04481    buf[0] = '\0';
04482    
04483    if (!group) /* Return empty string if no group */
04484       return buf;
04485 
04486    for (i = 0; i <= 63; i++) {   /* Max group is 63 */
04487       if (group & ((ast_group_t) 1 << i)) {
04488             if (!first) {
04489             strncat(buf, ", ", buflen - strlen(buf) - 1);
04490          } else {
04491             first=0;
04492          }
04493          snprintf(num, sizeof(num), "%u", i);
04494          strncat(buf, num, buflen - strlen(buf) - 1);
04495       }
04496    }
04497    return buf;
04498 }

int ast_prod ( struct ast_channel chan  ) 

Send empty audio to prime a channel driver.

Definition at line 2579 of file channel.c.

References ast_channel::_state, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), AST_STATE_UP, ast_write(), ast_frame::data, LOG_DEBUG, LOG_WARNING, option_debug, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.

Referenced by ast_activate_generator().

02580 {
02581    struct ast_frame a = { AST_FRAME_VOICE };
02582    char nothing[128];
02583 
02584    /* Send an empty audio frame to get things moving */
02585    if (chan->_state != AST_STATE_UP) {
02586       if (option_debug)
02587          ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
02588       a.subclass = chan->rawwriteformat;
02589       a.data = nothing + AST_FRIENDLY_OFFSET;
02590       a.src = "ast_prod";
02591       if (ast_write(chan, &a))
02592          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
02593    }
02594    return 0;
02595 }

int ast_queue_control ( struct ast_channel chan,
enum ast_control_frame_type  control 
)

int ast_queue_control_data ( struct ast_channel chan,
enum ast_control_frame_type  control,
const void *  data,
size_t  datalen 
)

Queue a control frame with payload.

Parameters:
chan channel to queue frame onto
control type of control frame
data pointer to payload data to be included in frame
datalen number of bytes of payload data
Returns:
zero on success, non-zero on failure
The supplied payload data is copied into the frame, so the caller's copy is not modified nor freed, and the resulting frame will retain a copy of the data even if the caller frees their local copy.

Note:
This method should be treated as a 'network transport'; in other words, your frames may be transferred across an IAX2 channel to another system, which may be a different endianness than yours. Because of this, you should ensure that either your frames will never be expected to work across systems, or that you always put your payload data into 'network byte order' before calling this function.

Definition at line 972 of file channel.c.

References AST_FRAME_CONTROL, ast_queue_frame(), ast_frame::data, ast_frame::datalen, and ast_frame::subclass.

Referenced by iax2_queue_control_data(), process_sdp(), skinny_hold(), zt_handle_event(), and zt_hangup().

00974 {
00975    struct ast_frame f = { AST_FRAME_CONTROL, };
00976 
00977    f.subclass = control;
00978    f.data = (void *) data;
00979    f.datalen = datalen;
00980 
00981    return ast_queue_frame(chan, &f);
00982 }

int ast_queue_frame ( struct ast_channel chan,
struct ast_frame fin 
)

Queue an outgoing frame.

Definition at line 894 of file channel.c.

References ast_channel::alertpipe, ast_assert, ast_channel_lock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FLAG_BLOCKING, AST_FRAME_CONTROL, AST_FRAME_VOICE, ast_frdup(), ast_frfree, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_TRAVERSE, ast_log(), ast_test_flag, ast_channel::blocker, errno, f, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, option_debug, ast_frame::subclass, and ast_channel::timingfd.

Referenced by __oh323_rtp_create(), __oh323_update_info(), agent_new(), alsa_call(), ast_autoservice_stop(), ast_channel_masquerade(), ast_channel_setwhentohangup(), ast_do_masquerade(), ast_dsp_process(), ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_softhangup_nolock(), cb_events(), console_answer(), console_answer_deprecated(), console_dial(), console_dial_deprecated(), console_flash(), console_flash_deprecated(), console_sendtext(), console_sendtext_deprecated(), dictate_exec(), do_immediate_setup(), gtalk_handle_dtmf(), handle_keypad_button_message(), handle_request_info(), handle_request_invite(), handle_response_invite(), iax2_queue_frame(), local_queue_frame(), mgcp_queue_frame(), oh323_simulate_dtmf_end(), oss_call(), process_sdp(), receive_digit(), receive_message(), rpt_call(), wakeup_sub(), and zap_queue_frame().

00895 {
00896    struct ast_frame *f;
00897    struct ast_frame *cur;
00898    int blah = 1;
00899    int qlen = 0;
00900 
00901    /* Build us a copy and free the original one */
00902    if (!(f = ast_frdup(fin))) {
00903       ast_log(LOG_WARNING, "Unable to duplicate frame\n");
00904       return -1;
00905    }
00906    ast_channel_lock(chan);
00907 
00908    /* See if the last frame on the queue is a hangup, if so don't queue anything */
00909    if ((cur = AST_LIST_LAST(&chan->readq)) && (cur->frametype == AST_FRAME_CONTROL) && (cur->subclass == AST_CONTROL_HANGUP)) {
00910       ast_frfree(f);
00911       ast_channel_unlock(chan);
00912       return 0;
00913    }
00914 
00915    /* Count how many frames exist on the queue */
00916    AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) {
00917       qlen++;
00918    }
00919 
00920    /* Allow up to 96 voice frames outstanding, and up to 128 total frames */
00921    if (((fin->frametype == AST_FRAME_VOICE) && (qlen > 96)) || (qlen  > 128)) {
00922       if (fin->frametype != AST_FRAME_VOICE) {
00923          ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
00924          ast_assert(0);
00925       } else {
00926          if (option_debug)
00927             ast_log(LOG_DEBUG, "Dropping voice to exceptionally long queue on %s\n", chan->name);
00928          ast_frfree(f);
00929          ast_channel_unlock(chan);
00930          return 0;
00931       }
00932    }
00933    AST_LIST_INSERT_TAIL(&chan->readq, f, frame_list);
00934    if (chan->alertpipe[1] > -1) {
00935       if (write(chan->alertpipe[1], &blah, sizeof(blah)) != sizeof(blah))
00936          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d (qlen = %d): %s!\n",
00937             chan->name, f->frametype, f->subclass, qlen, strerror(errno));
00938 #ifdef HAVE_ZAPTEL
00939    } else if (chan->timingfd > -1) {
00940       ioctl(chan->timingfd, ZT_TIMERPING, &blah);
00941 #endif            
00942    } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
00943       pthread_kill(chan->blocker, SIGURG);
00944    }
00945    ast_channel_unlock(chan);
00946    return 0;
00947 }

int ast_queue_hangup ( struct ast_channel chan  ) 

struct ast_frame* ast_read ( struct ast_channel chan  )  [read]

Reads a frame.

Parameters:
chan channel to read a frame from Read a frame.
Returns:
Returns a frame, or NULL on error. If it returns NULL, you best just stop reading frames and assume the channel has been disconnected.

Definition at line 2364 of file channel.c.

References __ast_read().

Referenced by __adsi_transmit_messages(), __ast_play_and_record(), __ast_request_and_dial_uniqueid(), adsi_careful_send(), agent_ack_sleep(), agent_read(), app_exec(), ast_feature_request_and_dial(), ast_generic_bridge(), ast_masq_autoanswer_login(), ast_masq_hold_call(), ast_masq_park_call(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_udptl_bridge(), ast_waitfordigit_full(), async_wait(), autoservice_run(), background_detect_exec(), bridge_native_loop(), bridge_p2p_loop(), builtin_atxfer(), channel_spy(), check_goto_on_transfer(), conf_exec(), conf_flush(), conf_run(), dictate_exec(), disa_exec(), do_autoanswer_thread(), do_holding_thread(), do_parking_thread(), do_waiting(), echo_exec(), features_read(), find_cache(), handle_invite_replaces(), handle_recordfile(), iax2_bridge(), iax_park_thread(), ices_exec(), isAnsweringMachine(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), record_exec(), recordthread(), rpt(), rpt_exec(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), sms_exec(), speech_background(), ss_thread(), wait_for_answer(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), waitstream_core(), and zt_bridge().

02365 {
02366    return __ast_read(chan, 0);
02367 }

struct ast_frame* ast_read_noaudio ( struct ast_channel chan  )  [read]

Reads a frame, returning AST_FRAME_NULL frame if audio. Read a frame.

Parameters:
chan channel to read a frame from
Returns:
Returns a frame, or NULL on error. If it returns NULL, you best just stop reading frames and assume the channel has been disconnected.
Note:
Audio is replaced with AST_FRAME_NULL to avoid transcode when the resulting audio is not necessary.

Definition at line 2369 of file channel.c.

References __ast_read().

Referenced by conf_run().

02370 {
02371    return __ast_read(chan, 1);
02372 }

int ast_readstring ( struct ast_channel c,
char *  s,
int  len,
int  timeout,
int  rtimeout,
char *  enders 
)

Reads multiple digits

Parameters:
c channel to read from
s string to read in to. Must be at least the size of your length
len how many digits to read (maximum)
timeout how long to timeout between digits
rtimeout timeout to wait on the first digit
enders digits to end the string Read in a digit string "s", max length "len", maximum timeout between digits "timeout" (-1 for none), terminated by anything in "enders". Give them rtimeout for the first digit. Returns 0 on normal return, or 1 on a timeout. In the case of a timeout, any digits that were read before the timeout will still be available in s. RETURNS 2 in full version when ctrlfd is available, NOT 1

Definition at line 3126 of file channel.c.

References ast_readstring_full().

Referenced by __adsi_transmit_messages(), ast_adsi_begin_download(), ast_adsi_get_cpeinfo(), ast_adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().

03127 {
03128    return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
03129 }

int ast_readstring_full ( struct ast_channel c,
char *  s,
int  len,
int  timeout,
int  rtimeout,
char *  enders,
int  audiofd,
int  ctrlfd 
)

Definition at line 3131 of file channel.c.

References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream.

Referenced by ast_app_getdata_full(), and ast_readstring().

03132 {
03133    int pos = 0;   /* index in the buffer where we accumulate digits */
03134    int to = ftimeout;
03135 
03136    /* Stop if we're a zombie or need a soft hangup */
03137    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03138       return -1;
03139    if (!len)
03140       return -1;
03141    for (;;) {
03142       int d;
03143       if (c->stream) {
03144          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
03145          ast_stopstream(c);
03146          usleep(1000);
03147          if (!d)
03148             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03149       } else {
03150          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03151       }
03152       if (d < 0)
03153          return -1;
03154       if (d == 0) {
03155          s[pos]='\0';
03156          return 1;
03157       }
03158       if (d == 1) {
03159          s[pos]='\0';
03160          return 2;
03161       }
03162       if (!strchr(enders, d))
03163          s[pos++] = d;
03164       if (strchr(enders, d) || (pos >= len)) {
03165          s[pos]='\0';
03166          return 0;
03167       }
03168       to = timeout;
03169    }
03170    /* Never reached */
03171    return 0;
03172 }

int ast_recvchar ( struct ast_channel chan,
int  timeout 
)

Receives a text character from a channel.

Parameters:
chan channel to act upon
timeout timeout in milliseconds (0 for infinite wait) Read a char of text from a channel Returns 0 on success, -1 on failure

Definition at line 2444 of file channel.c.

References ast_recvtext(), and free.

Referenced by handle_recvchar().

02445 {
02446    int c;
02447    char *buf = ast_recvtext(chan, timeout);
02448    if (buf == NULL)
02449       return -1;  /* error or timeout */
02450    c = *(unsigned char *)buf;
02451    free(buf);
02452    return c;
02453 }

char* ast_recvtext ( struct ast_channel chan,
int  timeout 
)

Receives a text string from a channel Read a string of text from a channel.

Parameters:
chan channel to act upon
timeout timeout in milliseconds (0 for infinite wait)
Returns:
the received text, or NULL to signify failure.

Definition at line 2455 of file channel.c.

References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree, ast_read(), ast_strndup, ast_waitfor(), ast_frame::data, ast_frame::datalen, f, ast_frame::frametype, and ast_frame::subclass.

Referenced by ast_recvchar(), and handle_recvtext().

02456 {
02457    int res, done = 0;
02458    char *buf = NULL;
02459    
02460    while (!done) {
02461       struct ast_frame *f;
02462       if (ast_check_hangup(chan))
02463          break;
02464       res = ast_waitfor(chan, timeout);
02465       if (res <= 0) /* timeout or error */
02466          break;
02467       timeout = res; /* update timeout */
02468       f = ast_read(chan);
02469       if (f == NULL)
02470          break; /* no frame */
02471       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
02472          done = 1;   /* force a break */
02473       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
02474          buf = ast_strndup((char *) f->data, f->datalen);   /* dup and break */
02475          done = 1;
02476       }
02477       ast_frfree(f);
02478    }
02479    return buf;
02480 }

struct ast_channel* ast_request ( const char *  type,
int  format,
void *  data,
int *  status 
) [read]

Requests a channel.

Parameters:
type type of channel to request
format requested channel format (codec)
data data to pass to the channel requester
status status Request a channel of a given type, with data as optional information used by the low level module
Returns:
Returns an ast_channel on success, NULL on failure.

Definition at line 3079 of file channel.c.

References ast_request_with_uniqueid().

Referenced by agent_request(), ast_feature_request_and_dial(), ast_send_message(), attempt_reconnect(), begin_dial(), build_conf(), chanavail_exec(), conf_run(), connect_link(), features_alloc(), findmeexec(), ring_entry(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), and wait_for_answer().

03080 {
03081     return ast_request_with_uniqueid(type, format, data, cause, NULL);
03082 }

struct ast_channel* ast_request_and_dial ( const char *  type,
int  format,
void *  data,
int  timeout,
int *  reason,
const char *  cidnum,
const char *  cidname 
) [read]

Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.

Parameters:
type type of channel to request
format requested channel format
data data to pass to the channel requester
timeout maximum amount of time to wait for an answer
reason why unsuccessful (if unsuceessful)
cidnum Caller-ID Number
cidname Caller-ID Name
Returns:
Returns an ast_channel on success or no answer, NULL on failure. Check the value of chan->_state to know if the call was answered or not.

Definition at line 3019 of file channel.c.

References __ast_request_and_dial().

03020 {
03021    return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
03022 }

struct ast_channel* ast_request_and_dial_uniqueid ( const char *  type,
int  format,
void *  data,
int  timeout,
int *  reason,
int  callingpres,
const char *  cidnum,
const char *  cidname,
char *  uniqueid 
) [read]

Definition at line 3023 of file channel.c.

References __ast_request_and_dial_uniqueid().

Referenced by ast_pbx_outgoing_exten_uniqueid().

03024 {
03025    return __ast_request_and_dial_uniqueid(type, format, data, timeout, outstate, 0, cidnum, cidname, NULL, uniqueid);
03026 }

struct ast_channel* ast_request_with_uniqueid ( const char *  type,
int  format,
void *  data,
int *  status,
char *  uniqueid 
) [read]

Requests a channel.

Parameters:
type type of channel to request
format requested channel format (codec)
data data to pass to the channel requester
status status
uniqueid uniqueid Request a channel of a given type, with data as optional information used by the low level module. Sets the channels uniqueid to 'uniqueid'.
Returns:
Returns an ast_channel on success, NULL on failure.

Definition at line 3028 of file channel.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_translator_best_choice(), ast_channel_tech::capabilities, capabilities, channels, fmt, LOG_WARNING, ast_channel_tech::requester, chanlist::tech, and ast_channel_tech::type.

Referenced by __ast_request_and_dial_uniqueid(), and ast_request().

03029 {
03030    struct chanlist *chan;
03031    struct ast_channel *c;
03032    int capabilities;
03033    int fmt;
03034    int res;
03035    int foo;
03036    int videoformat = format & AST_FORMAT_VIDEO_MASK;
03037 
03038    if (!cause)
03039       cause = &foo;
03040    *cause = AST_CAUSE_NOTDEFINED;
03041 
03042    if (AST_LIST_LOCK(&channels)) {
03043       ast_log(LOG_WARNING, "Unable to lock channel list\n");
03044       return NULL;
03045    }
03046 
03047    AST_LIST_TRAVERSE(&backends, chan, list) {
03048       if (strcasecmp(type, chan->tech->type))
03049          continue;
03050 
03051       capabilities = chan->tech->capabilities;
03052       fmt = format & AST_FORMAT_AUDIO_MASK;
03053       res = ast_translator_best_choice(&fmt, &capabilities);
03054       if (res < 0) {
03055          ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
03056          *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03057          AST_LIST_UNLOCK(&channels);
03058          return NULL;
03059       }
03060       AST_LIST_UNLOCK(&channels);
03061       if (!chan->tech->requester)
03062          return NULL;
03063       
03064       if (!(c = chan->tech->requester(type, capabilities | videoformat, data, cause)))
03065          return NULL;
03066 
03067       if (uniqueid) strncpy(c->uniqueid, uniqueid, sizeof(c->uniqueid));
03068       /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
03069       return c;
03070    }
03071 
03072    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
03073    *cause = AST_CAUSE_NOSUCHDRIVER;
03074    AST_LIST_UNLOCK(&channels);
03075 
03076    return NULL;
03077 }

int ast_safe_sleep ( struct ast_channel chan,
int  ms 
)

Wait for a specied amount of time, looking for hangups.

Parameters:
chan channel to wait for
ms length of time in milliseconds to sleep Waits for a specified amount of time, servicing the channel as required.
Returns:
returns -1 on hangup, otherwise 0.

Definition at line 1177 of file channel.c.

References ast_safe_sleep_conditional().

Referenced by __login_exec(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_dtmf_stream(), ast_senddigit(), builtin_parkcall(), dictate_exec(), flash_exec(), function_ilink(), mgcp_ss(), milliwatt_exec(), moh0_exec(), moh1_exec(), old_milliwatt_exec(), park_call_exec(), pbx_builtin_answer(), pbx_builtin_wait(), play_tone_pair(), playtone(), privacy_exec(), receive_ademco_contact_id(), rpt_call(), rpt_exec(), rpt_tele_thread(), send_morse(), send_tone_telemetry(), skinny_ss(), ss_thread(), testclient_exec(), testserver_exec(), try_calling(), wait_for_hangup(), wait_interval(), and zapateller_exec().

01178 {
01179    return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
01180 }

int ast_safe_sleep_conditional ( struct ast_channel chan,
int  ms,
int(*)(void *)  cond,
void *  data 
)

Wait for a specied amount of time, looking for hangups and a condition argument.

Parameters:
chan channel to wait for
ms length of time in milliseconds to sleep
cond a function pointer for testing continue condition
data argument to be passed to the condition test function
Returns:
returns -1 on hangup, otherwise 0. Waits for a specified amount of time, servicing the channel as required. If cond returns 0, this function returns.

Definition at line 1156 of file channel.c.

References ast_frfree, ast_read(), ast_waitfor(), cond, and f.

Referenced by __login_exec(), and ast_safe_sleep().

01157 {
01158    struct ast_frame *f;
01159 
01160    while (ms > 0) {
01161       if (cond && ((*cond)(data) == 0))
01162          return 0;
01163       ms = ast_waitfor(chan, ms);
01164       if (ms < 0)
01165          return -1;
01166       if (ms > 0) {
01167          f = ast_read(chan);
01168          if (!f)
01169             return -1;
01170          ast_frfree(f);
01171       }
01172    }
01173    return 0;
01174 }

char* ast_safe_string_alloc ( const char *  fmt,
  ... 
)

printf the string into a correctly sized mallocd buffer, and return the buffer

return a mallocd string with the result of sprintf of the fmt and following args

Definition at line 410 of file channel.c.

References ast_malloc, and len.

Referenced by features_new(), and zt_new().

00411 {
00412    char *b2, buf[1];
00413    int len;
00414    va_list args;
00415 
00416    va_start(args, fmt);
00417    len = vsnprintf(buf, 1, fmt, args);
00418    va_end(args);
00419 
00420    if (!(b2 = ast_malloc(len + 1)))
00421       return NULL;
00422 
00423    va_start(args, fmt);
00424    vsnprintf(b2, len + 1,  fmt, args);
00425    va_end(args);
00426 
00427    return b2;
00428 }

static int ast_select ( int  nfds,
fd_set *  rfds,
fd_set *  wfds,
fd_set *  efds,
struct timeval *  tvp 
) [inline, static]

Waits for activity on a group of channels.

Parameters:
nfds the maximum number of file descriptors in the sets
rfds file descriptors to check for read availability
wfds file descriptors to check for write availability
efds file descriptors to check for exceptions (OOB data)
tvp timeout while waiting for events This is the same as a standard select(), except it guarantees the behaviour where the passed struct timeval is updated with how much time was not slept while waiting for the specified events

Definition at line 1371 of file channel.h.

Referenced by do_autoanswer_thread(), do_holding_thread(), do_monitor(), do_parking_thread(), and sound_thread().

01372 {
01373 #ifdef __linux__
01374    return select(nfds, rfds, wfds, efds, tvp);
01375 #else
01376    if (tvp) {
01377       struct timeval tv, tvstart, tvend, tvlen;
01378       int res;
01379 
01380       tv = *tvp;
01381       gettimeofday(&tvstart, NULL);
01382       res = select(nfds, rfds, wfds, efds, tvp);
01383       gettimeofday(&tvend, NULL);
01384       timersub(&tvend, &tvstart, &tvlen);
01385       timersub(&tv, &tvlen, tvp);
01386       if (tvp->tv_sec < 0 || (tvp->tv_sec == 0 && tvp->tv_usec < 0)) {
01387          tvp->tv_sec = 0;
01388          tvp->tv_usec = 0;
01389       }
01390       return res;
01391    }
01392    else
01393       return select(nfds, rfds, wfds, efds, NULL);
01394 #endif
01395 }

int ast_send_message ( const char *  type,
void *  data,
char *  to,
char *  from,
char *  message,
int  ispdu 
)

"Requests" a channel for sending a message

Parameters:
type type of channel to request
data data to pass to the channel requester
status status Request a channel of a given type, with data as optional information used by the low level module
Returns:
Returns 0 on success, -1 on failure.

Definition at line 4586 of file channel.c.

References AST_FORMAT_SLINEAR, ast_hangup(), ast_request(), ast_sendmessage(), and ast_set_callerid().

Referenced by action_message(), and attempt_thread().

04586                                                                                                    {
04587    struct ast_channel *chan = NULL;
04588    int status;
04589    int res = -1;
04590 
04591    chan = ast_request(type, AST_FORMAT_SLINEAR, data, &status);
04592    if (chan) {
04593        if (from) {
04594       ast_set_callerid(chan, from, from, from);
04595        }
04596        res = ast_sendmessage(chan, to, message, ispdu);
04597        /* XXX what about message CDRs ??? XXX */
04598        ast_hangup(chan);
04599        return res;
04600    }
04601 
04602    return res;
04603 }

int ast_senddigit ( struct ast_channel chan,
char  digit 
)

Send a DTMF digit to a channel Send a DTMF digit to a channel.

Parameters:
chan channel to act upon
digit the DTMF digit to send, encoded in ASCII
Returns:
Returns 0 on success, -1 on failure

Definition at line 2569 of file channel.c.

References AST_DEFAULT_EMULATE_DTMF_DURATION, ast_safe_sleep(), ast_senddigit_begin(), ast_senddigit_end(), ast_channel_tech::send_digit_begin, and ast_channel::tech.

Referenced by ast_dtmf_stream(), do_dtmf_phone(), manager_play_dtmf(), and rpt_call().

02570 {
02571    if (chan->tech->send_digit_begin) {
02572       ast_senddigit_begin(chan, digit);
02573       ast_safe_sleep(chan, AST_DEFAULT_EMULATE_DTMF_DURATION);
02574    }
02575    
02576    return ast_senddigit_end(chan, digit, AST_DEFAULT_EMULATE_DTMF_DURATION);
02577 }

int ast_senddigit_begin ( struct ast_channel chan,
char  digit 
)

Definition at line 2510 of file channel.c.

References ast_log(), ast_playtones_start(), LOG_DEBUG, option_debug, ast_channel_tech::send_digit_begin, and ast_channel::tech.

Referenced by agent_digit_begin(), ast_senddigit(), ast_write(), and features_digit_begin().

02511 {
02512    /* Device does not support DTMF tones, lets fake
02513     * it by doing our own generation. */
02514    static const char* dtmf_tones[] = {
02515       "941+1336", /* 0 */
02516       "697+1209", /* 1 */
02517       "697+1336", /* 2 */
02518       "697+1477", /* 3 */
02519       "770+1209", /* 4 */
02520       "770+1336", /* 5 */
02521       "770+1477", /* 6 */
02522       "852+1209", /* 7 */
02523       "852+1336", /* 8 */
02524       "852+1477", /* 9 */
02525       "697+1633", /* A */
02526       "770+1633", /* B */
02527       "852+1633", /* C */
02528       "941+1633", /* D */
02529       "941+1209", /* * */
02530       "941+1477"  /* # */
02531    };
02532 
02533    if (!chan->tech->send_digit_begin)
02534       return 0;
02535 
02536    if (!chan->tech->send_digit_begin(chan, digit))
02537       return 0;
02538 
02539    if (digit >= '0' && digit <='9')
02540       ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
02541    else if (digit >= 'A' && digit <= 'D')
02542       ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
02543    else if (digit == '*')
02544       ast_playtones_start(chan, 0, dtmf_tones[14], 0);
02545    else if (digit == '#')
02546       ast_playtones_start(chan, 0, dtmf_tones[15], 0);
02547    else {
02548       /* not handled */
02549       if (option_debug)
02550          ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
02551    }
02552 
02553    return 0;
02554 }

int ast_senddigit_end ( struct ast_channel chan,
char  digit,
unsigned int  duration 
)

Definition at line 2556 of file channel.c.

References ast_playtones_stop(), ast_channel::generator, ast_channel_tech::send_digit_end, and ast_channel::tech.

Referenced by agent_digit_end(), ast_senddigit(), ast_write(), and features_digit_end().

02557 {
02558    int res = -1;
02559 
02560    if (chan->tech->send_digit_end)
02561       res = chan->tech->send_digit_end(chan, digit, duration);
02562 
02563    if (res && chan->generator)
02564       ast_playtones_stop(chan);
02565    
02566    return 0;
02567 }

int ast_sendmessage ( struct ast_channel chan,
const char *  dest,
const char *  text,
int  ispdu 
)

Sends message to a channel Write text to a display on a channel.

Parameters:
chan channel to act upon
dest destination number/user
text string of text to send on the channel
ispdu message is in PDU format
Returns:
Returns 0 on success, -1 on failure

Definition at line 2495 of file channel.c.

References ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, CHECK_BLOCKING, and ast_channel::tech.

Referenced by ast_send_message().

02496 {
02497    int res = 0;
02498    /* Stop if we're a zombie or need a soft hangup */
02499    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02500       return -1;
02501    CHECK_BLOCKING(chan);
02502 #if 0 /* we (Debian) disable that addition because of ABI breakage */
02503    if (chan->tech->send_message)
02504       res = chan->tech->send_message(chan, dest, text, ispdu);
02505 #endif
02506    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02507    return res;
02508 }

int ast_sendtext ( struct ast_channel chan,
const char *  text 
)

Sends text to a channel Write text to a display on a channel.

Parameters:
chan channel to act upon
text string of text to send on the channel
Returns:
Returns 0 on success, -1 on failure

Definition at line 2482 of file channel.c.

References ast_check_hangup(), ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_test_flag, CHECK_BLOCKING, ast_channel_tech::send_text, and ast_channel::tech.

Referenced by agent_sendtext(), handle_sendtext(), and sendtext_exec().

02483 {
02484    int res = 0;
02485    /* Stop if we're a zombie or need a soft hangup */
02486    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02487       return -1;
02488    CHECK_BLOCKING(chan);
02489    if (chan->tech->send_text)
02490       res = chan->tech->send_text(chan, text);
02491    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02492    return res;
02493 }

void ast_set_callerid ( struct ast_channel chan,
const char *  cidnum,
const char *  cidname,
const char *  ani 
)

Note:
The channel does not need to be locked before calling this function.

Definition at line 3685 of file channel.c.

References ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_describe_caller_presentation(), ast_strdup, ast_channel::cdr, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, EVENT_FLAG_CALL, free, manager_event(), and S_OR.

Referenced by __ast_request_and_dial_uniqueid(), agent_call(), ast_feature_request_and_dial(), ast_send_message(), callerid_write(), disa_exec(), findmeexec(), handle_setcallerid(), lookupcidname_exec(), mgcp_ss(), privacy_exec(), read_config(), rpt_exec(), setcallerid_exec(), skinny_newcall(), ss_thread(), wait_for_answer(), and zt_read().

03686 {
03687    ast_channel_lock(chan);
03688 
03689    if (callerid) {
03690       if (chan->cid.cid_num)
03691          free(chan->cid.cid_num);
03692       chan->cid.cid_num = ast_strdup(callerid);
03693    }
03694    if (calleridname) {
03695       if (chan->cid.cid_name)
03696          free(chan->cid.cid_name);
03697       chan->cid.cid_name = ast_strdup(calleridname);
03698    }
03699    if (ani) {
03700       if (chan->cid.cid_ani)
03701          free(chan->cid.cid_ani);
03702       chan->cid.cid_ani = ast_strdup(ani);
03703    }
03704    if (chan->cdr)
03705       ast_cdr_setcid(chan->cdr, chan);
03706    manager_event(EVENT_FLAG_CALL, "Newcallerid",
03707             "Channel: %s\r\n"
03708             "CallerID: %s\r\n"
03709             "CallerIDName: %s\r\n"
03710             "Uniqueid: %s\r\n"
03711             "CID-CallingPres: %d (%s)\r\n",
03712             chan->name,
03713             S_OR(chan->cid.cid_num, "<Unknown>"),
03714             S_OR(chan->cid.cid_name, "<Unknown>"),
03715             chan->uniqueid,
03716             chan->cid.cid_pres,
03717             ast_describe_caller_presentation(chan->cid.cid_pres)
03718             );
03719    
03720    ast_channel_unlock(chan);
03721 }

int ast_set_read_format ( struct ast_channel chan,
int  format 
)

void ast_set_variables ( struct ast_channel chan,
struct ast_variable vars 
)

adds a list of channel variables to a channel

Parameters:
chan the channel
vars a linked list of variables
Variable names can be for a regular channel variable or a dialplan function that has the ability to be written to.

Definition at line 4500 of file channel.c.

References ast_variable::name, ast_variable::next, pbx_builtin_setvar_helper(), and ast_variable::value.

Referenced by __ast_request_and_dial_uniqueid(), ast_pbx_outgoing_app_uniqueid(), and ast_pbx_outgoing_exten_uniqueid().

04501 {
04502    struct ast_variable *cur;
04503 
04504    for (cur = vars; cur; cur = cur->next)
04505       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
04506 }

int ast_set_write_format ( struct ast_channel chan,
int  format 
)

int ast_setstate ( struct ast_channel chan,
enum ast_channel_state  state 
)

int ast_setstate_and_callerid ( struct ast_channel chan,
enum ast_channel_state  state,
char *  cid_num,
char *  cid_name 
)

Change the state of a channel and the callerid of the calling channel.

Definition at line 3723 of file channel.c.

References ast_channel::_state, ast_device_state_changed_literal(), ast_state2str(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, EVENT_FLAG_CALL, manager_event(), and S_OR.

Referenced by ast_setstate().

03724 {
03725    int oldstate = chan->_state;
03726 
03727    if (oldstate == state)
03728       return 0;
03729 
03730    chan->_state = state;
03731    ast_device_state_changed_literal(chan->name, cid_num, cid_name);
03732    /* setstate used to conditionally report Newchannel; this is no more */
03733    manager_event(EVENT_FLAG_CALL,
03734             "Newstate",
03735             "Channel: %s\r\n"
03736             "State: %s\r\n"
03737             "CallerID: %s\r\n"
03738             "CallerIDName: %s\r\n"
03739             "Uniqueid: %s\r\n",
03740             chan->name, ast_state2str(chan->_state),
03741             S_OR(chan->cid.cid_num, "<unknown>"),
03742             S_OR(chan->cid.cid_name, "<unknown>"),
03743             chan->uniqueid);
03744 
03745    return 0;
03746 }

int ast_settimeout ( struct ast_channel c,
int  samples,
int(*)(const void *data)  func,
void *  data 
)

Definition at line 1811 of file channel.c.

References ast_log(), func, LOG_DEBUG, option_debug, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.

Referenced by ast_activate_generator(), ast_closestream(), ast_deactivate_generator(), ast_read_generator_actions(), and ast_readaudio_callback().

01812 {
01813    int res = -1;
01814 #ifdef HAVE_ZAPTEL
01815    if (c->timingfd > -1) {
01816       if (!func) {
01817          samples = 0;
01818          data = 0;
01819       }
01820       if (option_debug)
01821          ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01822       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01823       c->timingfunc = func;
01824       c->timingdata = data;
01825    }
01826 #endif   
01827    return res;
01828 }

int ast_shutting_down ( void   ) 

Returns non-zero if Asterisk is being shut down.

Returns non-zero if Asterisk is being shut down

Definition at line 462 of file channel.c.

Referenced by handle_request_options().

00463 {
00464    return shutting_down;
00465 }

int ast_softhangup ( struct ast_channel chan,
int  cause 
)

Softly hangup up a channel.

Parameters:
chan channel to be soft-hung-up Call the protocol layer, but don't destroy the channel structure (use this if you are trying to safely hangup a channel managed by another thread.
cause Ast hangupcause for hangup
Returns:
Returns 0 regardless

Definition at line 1412 of file channel.c.

References ast_channel_lock, ast_channel_unlock, and ast_softhangup_nolock().

Referenced by __ast_module_user_hangup_all(), __ast_pbx_run(), __login_exec(), __unload_module(), action_hangup(), agent_hangup(), agent_logoff(), ast_begin_shutdown(), ast_dial_join(), connect_link(), function_ilink(), handle_hangup(), handle_link_data(), handle_softhangup(), manager_park(), read_agent_config(), rpt(), rpt_call(), rpt_do_restart(), sla_handle_hold_event(), softhangup_exec(), start_spying(), startmon(), unload_module(), and zt_handle_event().

01413 {
01414    int res;
01415    ast_channel_lock(chan);
01416    res = ast_softhangup_nolock(chan, cause);
01417    ast_channel_unlock(chan);
01418    return res;
01419 }

int ast_softhangup_nolock ( struct ast_channel chan,
int  cause 
)

Softly hangup up a channel (no channel lock).

Parameters:
chan channel to be soft-hung-up
cause Ast hangupcause for hangup (see cause.h)

Definition at line 1398 of file channel.c.

References ast_channel::_softhangup, AST_FLAG_BLOCKING, ast_log(), ast_null_frame, ast_queue_frame(), ast_test_flag, ast_channel::blocker, LOG_DEBUG, and option_debug.

Referenced by ast_async_goto(), ast_softhangup(), attempt_transfer(), do_monitor(), oh323_indicate(), sip_indicate(), and skinny_indicate().

01399 {
01400    if (option_debug)
01401       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
01402    /* Inform channel driver that we need to be hung up, if it cares */
01403    chan->_softhangup |= cause;
01404    ast_queue_frame(chan, &ast_null_frame);
01405    /* Interrupt any poll call or such */
01406    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
01407       pthread_kill(chan->blocker, SIGURG);
01408    return 0;
01409 }

char* ast_state2str ( enum  ast_channel_state  ) 

Gives the string form of a given channel state.

Gives the string form of a given channel state

Parameters:
ast_channel_state state to get the name of Give a name to a state Returns the text form of the binary state given

Definition at line 601 of file channel.c.

References AST_STATE_BUSY, AST_STATE_DIALING, AST_STATE_DIALING_OFFHOOK, AST_STATE_DOWN, AST_STATE_OFFHOOK, AST_STATE_PRERING, AST_STATE_RESERVED, AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, and STATE2STR_BUFSIZE.

Referenced by action_status(), agent_hangup(), ast_channel_alloc(), ast_setstate_and_callerid(), attempt_transfer(), func_channel_read(), handle_chanlist(), handle_chanlist_deprecated(), handle_invite_replaces(), handle_showchan(), handle_showchan_deprecated(), local_attended_transfer(), mgcp_new(), serialize_showchan(), and sip_hangup().

00602 {
00603    char *buf;
00604 
00605    switch(state) {
00606    case AST_STATE_DOWN:
00607       return "Down";
00608    case AST_STATE_RESERVED:
00609       return "Rsrvd";
00610    case AST_STATE_OFFHOOK:
00611       return "OffHook";
00612    case AST_STATE_DIALING:
00613       return "Dialing";
00614    case AST_STATE_RING:
00615       return "Ring";
00616    case AST_STATE_RINGING:
00617       return "Ringing";
00618    case AST_STATE_UP:
00619       return "Up";
00620    case AST_STATE_BUSY:
00621       return "Busy";
00622    case AST_STATE_DIALING_OFFHOOK:
00623       return "Dialing Offhook";
00624    case AST_STATE_PRERING:
00625       return "Pre-ring";
00626    default:
00627       if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE)))
00628          return "Unknown";
00629       snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state);
00630       return buf;
00631    }
00632 }

int ast_str2cause ( const char *  name  ) 

Convert a symbolic hangup cause to number.

Convert the string form of a cause code to a number

Parameters:
name string form of the cause Returns the cause code

Definition at line 589 of file channel.c.

References causes.

Referenced by pbx_builtin_hangup().

00590 {
00591    int x;
00592 
00593    for (x = 0; x < sizeof(causes) / sizeof(causes[0]); x++)
00594       if (strncasecmp(causes[x].name, name, strlen(causes[x].name)) == 0)
00595          return causes[x].cause;
00596 
00597    return -1;
00598 }

int ast_tonepair ( struct ast_channel chan,
int  freq1,
int  freq2,
int  duration,
int  vol 
)

Play a tone pair for a given amount of time

Definition at line 4372 of file channel.c.

References ast_frfree, ast_read(), ast_tonepair_start(), ast_waitfor(), f, and ast_channel::generatordata.

Referenced by zapateller_exec().

04373 {
04374    int res;
04375 
04376    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
04377       return res;
04378 
04379    /* Give us some wiggle room */
04380    while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
04381       struct ast_frame *f = ast_read(chan);
04382       if (f)
04383          ast_frfree(f);
04384       else
04385          return -1;
04386    }
04387    return 0;
04388 }

int ast_tonepair_start ( struct ast_channel chan,
int  freq1,
int  freq2,
int  duration,
int  vol 
)

Start a tone going

Definition at line 4354 of file channel.c.

References ast_activate_generator(), tonepair_def::duration, tonepair_def::freq1, tonepair_def::freq2, tonepair, and tonepair_def::vol.

Referenced by ast_tonepair(), play_dialtone(), play_tone_pair(), rpt_tele_thread(), and sendnoise().

04355 {
04356    struct tonepair_def d = { 0, };
04357 
04358    d.freq1 = freq1;
04359    d.freq2 = freq2;
04360    d.duration = duration;
04361    d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */
04362    if (ast_activate_generator(chan, &tonepair, &d))
04363       return -1;
04364    return 0;
04365 }

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 4367 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

04368 {
04369    ast_deactivate_generator(chan);
04370 }

int ast_transfer ( struct ast_channel chan,
char *  dest 
)

Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.

Parameters:
chan current channel
dest destination extension for transfer
Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.

Called by:

  • app_transfer
  • the manager interface

Definition at line 3108 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_FLAG_ZOMBIE, ast_test_flag, ast_channel::tech, and ast_channel_tech::transfer.

Referenced by transfer_exec().

03109 {
03110    int res = -1;
03111 
03112    /* Stop if we're a zombie or need a soft hangup */
03113    ast_channel_lock(chan);
03114    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03115       if (chan->tech->transfer) {
03116          res = chan->tech->transfer(chan, dest);
03117          if (!res)
03118             res = 1;
03119       } else
03120          res = 0;
03121    }
03122    ast_channel_unlock(chan);
03123    return res;
03124 }

char* ast_transfercapability2str ( int  transfercapability  )  const

Gives the string form of a given transfer capability.

Gives the string form of a given transfer capability

Parameters:
transfercapability transfercapabilty to get the name of Give a name to a transfercapbility See above Returns the text form of the binary transfer capbility

Definition at line 635 of file channel.c.

References AST_TRANS_CAP_3_1K_AUDIO, AST_TRANS_CAP_DIGITAL, AST_TRANS_CAP_DIGITAL_W_TONES, AST_TRANS_CAP_RESTRICTED_DIGITAL, AST_TRANS_CAP_SPEECH, and AST_TRANS_CAP_VIDEO.

Referenced by cb_events(), misdn_call(), oh323_call(), zt_call(), and zt_new().

00636 {
00637    switch(transfercapability) {
00638    case AST_TRANS_CAP_SPEECH:
00639       return "SPEECH";
00640    case AST_TRANS_CAP_DIGITAL:
00641       return "DIGITAL";
00642    case AST_TRANS_CAP_RESTRICTED_DIGITAL:
00643       return "RESTRICTED_DIGITAL";
00644    case AST_TRANS_CAP_3_1K_AUDIO:
00645       return "3K1AUDIO";
00646    case AST_TRANS_CAP_DIGITAL_W_TONES:
00647       return "DIGITAL_W_TONES";
00648    case AST_TRANS_CAP_VIDEO:
00649       return "VIDEO";
00650    default:
00651       return "UNKNOWN";
00652    }
00653 }

int ast_waitfor ( struct ast_channel chan,
int  ms 
)

Wait for input on a channel.

Parameters:
chan channel to wait on
ms length of time to wait on the channel Wait for input on a channel for a given # of milliseconds (<0 for indefinite).
Returns:
Returns < 0 on failure, 0 if nothing ever arrived, and the # of ms remaining otherwise

Definition at line 1795 of file channel.c.

References ast_waitfor_nandfds().

Referenced by __adsi_transmit_messages(), __ast_play_and_record(), __ast_request_and_dial_uniqueid(), adsi_careful_send(), agent_ack_sleep(), ast_dtmf_stream(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), async_wait(), background_detect_exec(), channel_spy(), conf_exec(), conf_flush(), dictate_exec(), disa_exec(), do_waiting(), echo_exec(), handle_recordfile(), ices_exec(), isAnsweringMachine(), measurenoise(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), record_exec(), recordthread(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), sms_exec(), speech_background(), ss_thread(), wait_for_hangup(), waitforring_exec(), and waitstream_core().

01796 {
01797    int oldms = ms;   /* -1 if no timeout */
01798 
01799    ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
01800    if ((ms < 0) && (oldms < 0))
01801       ms = 0;
01802    return ms;
01803 }

struct ast_channel* ast_waitfor_n ( struct ast_channel **  chan,
int  n,
int *  ms 
) [read]

Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds.

Returns:
Return channel with activity, or NULL if none has activity.
Parameters:
chan an array of pointers to channels
n number of channels that are to be waited upon
ms time "ms" is modified in-place, if applicable

Definition at line 1790 of file channel.c.

References ast_waitfor_nandfds().

Referenced by ast_feature_request_and_dial(), ast_generic_bridge(), ast_udptl_bridge(), autoservice_run(), bridge_native_loop(), bridge_p2p_loop(), iax2_bridge(), misdn_bridge(), monitor_dial(), rpt(), rpt_exec(), wait_for_answer(), wait_for_winner(), and zt_bridge().

01791 {
01792    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
01793 }

int ast_waitfor_n_fd ( int *  fds,
int  n,
int *  ms,
int *  exception 
)

Waits for input on an fd This version works on fd's only. Be careful with it.

Definition at line 1634 of file channel.c.

References ast_waitfor_nandfds().

Referenced by dundi_lookup_internal(), and dundi_precache_internal().

01635 {
01636    int winner = -1;
01637    ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
01638    return winner;
01639 }

struct ast_channel* ast_waitfor_nandfds ( struct ast_channel **  c,
int  n,
int *  fds,
int  nfds,
int *  exception,
int *  outfd,
int *  ms 
) [read]

Waits for activity on a group of channels.

Parameters:
chan an array of pointers to channels
n number of channels that are to be waited upon
fds an array of fds to wait upon
nfds the number of fds to wait upon
exception exception flag
outfd fd that had activity on it
ms how long the wait was Big momma function here. Wait for activity on any of the n channels, or any of the nfds file descriptors.
Returns:
Returns the channel with activity, or NULL on error or if an FD came first. If the FD came first, it will be returned in outfd, otherwise, outfd will be -1

Definition at line 1642 of file channel.c.

References ast_channel::_softhangup, ast_add_fd(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, ast_log(), AST_MAX_FDS, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, CHECK_BLOCKING, errno, pollfd::fd, ast_channel::fdno, LOG_WARNING, poll(), POLLPRI, pollfd::revents, and ast_channel::whentohangup.

Referenced by app_exec(), ast_waitfor(), ast_waitfor_n(), ast_waitfor_n_fd(), ast_waitfordigit_full(), conf_run(), find_cache(), run_agi(), and waitstream_core().

01644 {
01645    struct timeval start = { 0 , 0 };
01646    struct pollfd *pfds = NULL;
01647    int res;
01648    long rms;
01649    int x, y, max;
01650    int sz;
01651    time_t now = 0;
01652    long whentohangup = 0, diff;
01653    struct ast_channel *winner = NULL;
01654    struct fdmap {
01655       int chan;
01656       int fdno;
01657    } *fdmap = NULL;
01658 
01659    if ((sz = n * AST_MAX_FDS + nfds)) {
01660       pfds = alloca(sizeof(*pfds) * sz);
01661       fdmap = alloca(sizeof(*fdmap) * sz);
01662    }
01663 
01664    if (outfd)
01665       *outfd = -99999;
01666    if (exception)
01667       *exception = 0;
01668    
01669    /* Perform any pending masquerades */
01670    for (x=0; x < n; x++) {
01671       ast_channel_lock(c[x]);
01672       if (c[x]->masq) {
01673          if (ast_do_masquerade(c[x])) {
01674             ast_log(LOG_WARNING, "Masquerade failed\n");
01675             *ms = -1;
01676             ast_channel_unlock(c[x]);
01677             return NULL;
01678          }
01679       }
01680       if (c[x]->whentohangup) {
01681          if (!whentohangup)
01682             time(&now);
01683          diff = c[x]->whentohangup - now;
01684          if (diff < 1) {
01685             /* Should already be hungup */
01686             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
01687             ast_channel_unlock(c[x]);
01688             return c[x];
01689          }
01690          if (!whentohangup || (diff < whentohangup))
01691             whentohangup = diff;
01692       }
01693       ast_channel_unlock(c[x]);
01694    }
01695    /* Wait full interval */
01696    rms = *ms;
01697    if (whentohangup) {
01698       rms = whentohangup * 1000;              /* timeout in milliseconds */
01699       if (*ms >= 0 && *ms < rms)    /* original *ms still smaller */
01700          rms =  *ms;
01701    }
01702    /*
01703     * Build the pollfd array, putting the channels' fds first,
01704     * followed by individual fds. Order is important because
01705     * individual fd's must have priority over channel fds.
01706     */
01707    max = 0;
01708    for (x=0; x<n; x++) {
01709       for (y=0; y<AST_MAX_FDS; y++) {
01710          fdmap[max].fdno = y;  /* fd y is linked to this pfds */
01711          fdmap[max].chan = x;  /* channel x is linked to this pfds */
01712          max += ast_add_fd(&pfds[max], c[x]->fds[y]);
01713       }
01714       CHECK_BLOCKING(c[x]);
01715    }
01716    /* Add the individual fds */
01717    for (x=0; x<nfds; x++) {
01718       fdmap[max].chan = -1;
01719       max += ast_add_fd(&pfds[max], fds[x]);
01720    }
01721 
01722    if (*ms > 0)
01723       start = ast_tvnow();
01724    
01725    if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */
01726       do {
01727          int kbrms = rms;
01728          if (kbrms > 600000)
01729             kbrms = 600000;
01730          res = poll(pfds, max, kbrms);
01731          if (!res)
01732             rms -= kbrms;
01733       } while (!res && (rms > 0));
01734    } else {
01735       res = poll(pfds, max, rms);
01736    }
01737    for (x=0; x<n; x++)
01738       ast_clear_flag(c[x], AST_FLAG_BLOCKING);
01739    if (res < 0) { /* Simulate a timeout if we were interrupted */
01740       if (errno != EINTR)
01741          *ms = -1;
01742       return NULL;
01743    }
01744    if (whentohangup) {   /* if we have a timeout, check who expired */
01745       time(&now);
01746       for (x=0; x<n; x++) {
01747          if (c[x]->whentohangup && now >= c[x]->whentohangup) {
01748             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
01749             if (winner == NULL)
01750                winner = c[x];
01751          }
01752       }
01753    }
01754    if (res == 0) { /* no fd ready, reset timeout and done */
01755       *ms = 0; /* XXX use 0 since we may not have an exact timeout. */
01756       return winner;
01757    }
01758    /*
01759     * Then check if any channel or fd has a pending event.
01760     * Remember to check channels first and fds last, as they
01761     * must have priority on setting 'winner'
01762     */
01763    for (x = 0; x < max; x++) {
01764       res = pfds[x].revents;
01765       if (res == 0)
01766          continue;
01767       if (fdmap[x].chan >= 0) {  /* this is a channel */
01768          winner = c[fdmap[x].chan]; /* override previous winners */
01769          if (res & POLLPRI)
01770             ast_set_flag(winner, AST_FLAG_EXCEPTION);
01771          else
01772             ast_clear_flag(winner, AST_FLAG_EXCEPTION);
01773          winner->fdno = fdmap[x].fdno;
01774       } else {       /* this is an fd */
01775          if (outfd)
01776             *outfd = pfds[x].fd;
01777          if (exception)
01778             *exception = (res & POLLPRI) ? -1 : 0;
01779          winner = NULL;
01780       }
01781    }
01782    if (*ms > 0) {
01783       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
01784       if (*ms < 0)
01785          *ms = 0;
01786    }
01787    return winner;
01788 }

int ast_waitfordigit ( struct ast_channel c,
int  ms 
)

int ast_waitfordigit_full ( struct ast_channel c,
int  ms,
int  audiofd,
int  ctrlfd 
)

Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.

Parameters:
c channel to wait for a digit on
ms how many milliseconds to wait
audiofd audio file descriptor to write to if audio frames are received
ctrlfd control file descriptor to monitor for reading
Returns:
Returns 1 if ctrlfd becomes available

Definition at line 1830 of file channel.c.

References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_flag, ast_test_flag, ast_waitfor_nandfds(), ast_frame::data, ast_frame::datalen, errno, f, ast_frame::frametype, LOG_WARNING, and ast_frame::subclass.

Referenced by ast_readstring_full(), ast_waitfordigit(), handle_getoption(), and handle_waitfordigit().

01831 {
01832    /* Stop if we're a zombie or need a soft hangup */
01833    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
01834       return -1;
01835 
01836    /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */
01837    ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
01838 
01839    /* Wait for a digit, no more than ms milliseconds total. */
01840    while (ms) {
01841       struct ast_channel *rchan;
01842       int outfd;
01843 
01844       errno = 0;
01845       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
01846       if (!rchan && outfd < 0 && ms) {
01847          if (errno == 0 || errno == EINTR)
01848             continue;
01849          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
01850          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01851          return -1;
01852       } else if (outfd > -1) {
01853          /* The FD we were watching has something waiting */
01854          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01855          return 1;
01856       } else if (rchan) {
01857          int res;
01858          struct ast_frame *f = ast_read(c);
01859          if (!f)
01860             return -1;
01861 
01862          switch(f->frametype) {
01863          case AST_FRAME_DTMF_BEGIN:
01864             break;
01865          case AST_FRAME_DTMF_END:
01866             res = f->subclass;
01867             ast_frfree(f);
01868             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01869             return res;
01870          case AST_FRAME_CONTROL:
01871             switch(f->subclass) {
01872             case AST_CONTROL_HANGUP:
01873                ast_frfree(f);
01874                ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01875                return -1;
01876             case AST_CONTROL_RINGING:
01877             case AST_CONTROL_ANSWER:
01878             case AST_CONTROL_SRCUPDATE:
01879             case AST_CONTROL_SRCCHANGE:
01880                /* Unimportant */
01881                break;
01882             default:
01883                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
01884                break;
01885             }
01886             break;
01887          case AST_FRAME_VOICE:
01888             /* Write audio if appropriate */
01889             if (audiofd > -1)
01890                write(audiofd, f->data, f->datalen);
01891          default:
01892             /* Ignore */
01893             break;
01894          }
01895          ast_frfree(f);
01896       }
01897    }
01898 
01899    ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
01900 
01901    return 0; /* Time is up */
01902 }

struct ast_channel* ast_walk_channel_by_exten_locked ( const struct ast_channel chan,
const char *  exten,
const char *  context 
) [read]

Get next channel by exten (and optionally context) and lock it.

Definition at line 1144 of file channel.c.

References channel_find_locked().

Referenced by next_channel().

01146 {
01147    return channel_find_locked(chan, NULL, 0, context, exten, NULL);
01148 }

struct ast_channel* ast_walk_channel_by_name_prefix_locked ( const struct ast_channel chan,
const char *  name,
const int  namelen 
) [read]

Get channel by name prefix (locks channel).

Definition at line 1131 of file channel.c.

References channel_find_locked().

Referenced by next_channel().

01133 {
01134    return channel_find_locked(chan, name, namelen, NULL, NULL, NULL);
01135 }

int ast_write ( struct ast_channel chan,
struct ast_frame frame 
)

Write a frame to a channel This function writes the given frame to the indicated channel.

Parameters:
chan destination channel of the frame
frame frame that will be written
Returns:
It returns 0 on success, -1 on failure.

Todo:
XXX should return 0 maybe ?

Definition at line 2608 of file channel.c.

References ast_channel::_softhangup, AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_write_list(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_deactivate_generator(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_log(), AST_MONITOR_RUNNING, ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), ast_channel::audiohooks, CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, f, ast_channel::fout, FRAMECOUNT_INC, ast_frame::frametype, ast_channel::generatordata, ast_channel_tech::indicate, ast_channel::insmpl, ast_frame::len, LOG_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, option_debug, ast_channel::outsmpl, ast_channel::rawwriteformat, ast_frame::samples, SEEK_FORCECUR, ast_channel_tech::send_html, ast_channel_tech::send_text, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_video, and ast_channel::writetrans.

Referenced by adsi_careful_send(), agent_write(), ast_generic_bridge(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_udptl_bridge(), ast_write_video(), bridge_native_loop(), bridge_p2p_loop(), conf_queue_dtmf(), conf_run(), dictate_exec(), echo_exec(), features_write(), function_ilink(), gen_generate(), handle_link_data(), iax2_bridge(), jb_get_and_deliver(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), NBScat_exec(), playtones_generator(), rpt(), rpt_exec(), run_agi(), send_link_dtmf(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), sms_generate(), spy_generate(), tonepair_generator(), wait_for_answer(), and zt_bridge().

02609 {
02610    int res = -1;
02611    int count = 0;
02612    struct ast_frame *f = NULL, *f2 = NULL;
02613 
02614    /*Deadlock avoidance*/
02615    while(ast_channel_trylock(chan)) {
02616       /*cannot goto done since the channel is not locked*/
02617       if(count++ > 10) {
02618          if(option_debug)
02619             ast_log(LOG_DEBUG, "Deadlock avoided for write to channel '%s'\n", chan->name);
02620          return 0;
02621       }
02622       usleep(1);
02623    }
02624    /* Stop if we're a zombie or need a soft hangup */
02625    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02626       goto done;
02627 
02628    /* Handle any pending masquerades */
02629    if (chan->masq && ast_do_masquerade(chan)) {
02630       ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02631       goto done;
02632    }
02633    if (chan->masqr) {
02634       res = 0; /* XXX explain, why 0 ? */
02635       goto done;
02636    }
02637    if (chan->generatordata) {
02638       if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
02639          ast_deactivate_generator(chan);
02640       else {
02641          if (fr->frametype == AST_FRAME_DTMF_END) {
02642             /* There is a generator running while we're in the middle of a digit.
02643              * It's probably inband DTMF, so go ahead and pass it so it can
02644              * stop the generator */
02645             ast_clear_flag(chan, AST_FLAG_BLOCKING);
02646             ast_channel_unlock(chan);
02647             res = ast_senddigit_end(chan, fr->subclass, fr->len);
02648             ast_channel_lock(chan);
02649             CHECK_BLOCKING(chan);
02650          } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass == AST_CONTROL_UNHOLD) {
02651             /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */
02652             res = (chan->tech->indicate == NULL) ? 0 :
02653                chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
02654          }
02655          res = 0; /* XXX explain, why 0 ? */
02656          goto done;
02657       }
02658    }
02659    /* High bit prints debugging */
02660    if (chan->fout & DEBUGCHAN_FLAG)
02661       ast_frame_dump(chan->name, fr, ">>");
02662    CHECK_BLOCKING(chan);
02663    switch(fr->frametype) {
02664    case AST_FRAME_CONTROL:
02665       res = (chan->tech->indicate == NULL) ? 0 :
02666          chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
02667       break;
02668    case AST_FRAME_DTMF_BEGIN:
02669       if (chan->audiohooks) {
02670          struct ast_frame *old_frame = fr;
02671          fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02672          if (old_frame != fr)
02673             f = fr;
02674       }
02675       ast_clear_flag(chan, AST_FLAG_BLOCKING);
02676       ast_channel_unlock(chan);
02677       res = ast_senddigit_begin(chan, fr->subclass);
02678       ast_channel_lock(chan);
02679       CHECK_BLOCKING(chan);
02680       break;
02681    case AST_FRAME_DTMF_END:
02682       if (chan->audiohooks) {
02683          struct ast_frame *old_frame = fr;
02684          fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02685          if (old_frame != fr)
02686             f = fr;
02687       }
02688       ast_clear_flag(chan, AST_FLAG_BLOCKING);
02689       ast_channel_unlock(chan);
02690       res = ast_senddigit_end(chan, fr->subclass, fr->len);
02691       ast_channel_lock(chan);
02692       CHECK_BLOCKING(chan);
02693       break;
02694    case AST_FRAME_TEXT:
02695       res = (chan->tech->send_text == NULL) ? 0 :
02696          chan->tech->send_text(chan, (char *) fr->data);
02697       break;
02698    case AST_FRAME_HTML:
02699       res = (chan->tech->send_html == NULL) ? 0 :
02700          chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
02701       break;
02702    case AST_FRAME_VIDEO:
02703       /* XXX Handle translation of video codecs one day XXX */
02704       res = (chan->tech->write_video == NULL) ? 0 :
02705          chan->tech->write_video(chan, fr);
02706       break;
02707    case AST_FRAME_MODEM:
02708       res = (chan->tech->write == NULL) ? 0 :
02709          chan->tech->write(chan, fr);
02710       break;
02711    case AST_FRAME_VOICE:
02712       if (chan->tech->write == NULL)
02713          break;   /*! \todo XXX should return 0 maybe ? */
02714 
02715       if (chan->audiohooks) {
02716          struct ast_frame *old_frame = fr;
02717          fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02718          if (old_frame != fr)
02719             f2 = fr;
02720       }
02721       
02722       /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
02723       if (fr->subclass == chan->rawwriteformat)
02724          f = fr;
02725       else
02726          f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
02727 
02728       /* If we have no frame of audio, then we have to bail out */
02729       if (!f) {
02730          res = 0;
02731          break;
02732       }
02733 
02734       /* If Monitor is running on this channel, then we have to write frames out there too */
02735       if (chan->monitor && chan->monitor->write_stream) {
02736          /* XXX must explain this code */
02737 #ifndef MONITOR_CONSTANT_DELAY
02738          int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
02739          if (jump >= 0) {
02740             jump = chan->insmpl - chan->outsmpl;
02741             if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
02742                ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02743             chan->outsmpl += jump + f->samples;
02744          } else
02745             chan->outsmpl += f->samples;
02746 #else
02747          int jump = chan->insmpl - chan->outsmpl;
02748          if (jump - MONITOR_DELAY >= 0) {
02749             if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02750                ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02751             chan->outsmpl += jump;
02752          } else
02753             chan->outsmpl += f->samples;
02754 #endif
02755          if (chan->monitor->state == AST_MONITOR_RUNNING) {
02756             if (ast_writestream(chan->monitor->write_stream, f) < 0)
02757                ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
02758          }
02759       }
02760 
02761       if (f) 
02762          res = chan->tech->write(chan,f);
02763       else
02764          res = 0;
02765       break;
02766    case AST_FRAME_NULL:
02767    case AST_FRAME_IAX:
02768       /* Ignore these */
02769       res = 0;
02770       break;
02771    default:
02772       /* At this point, fr is the incoming frame and f is NULL.  Channels do
02773        * not expect to get NULL as a frame pointer and will segfault.  Hence,
02774        * we output the original frame passed in. */
02775       res = chan->tech->write(chan, fr);
02776       break;
02777    }
02778 
02779    if (f && f != fr)
02780       ast_frfree(f);
02781    if (f2)
02782       ast_frfree(f2);
02783    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02784    /* Consider a write failure to force a soft hangup */
02785    if (res < 0)
02786       chan->_softhangup |= AST_SOFTHANGUP_DEV;
02787    else {
02788       chan->fout = FRAMECOUNT_INC(chan->fout);
02789    }
02790 done:
02791    ast_channel_unlock(chan);
02792    return res;
02793 }

int ast_write_video ( struct ast_channel chan,
struct ast_frame frame 
)

Write video frame to a channel This function writes the given frame to the indicated channel.

Parameters:
chan destination channel of the frame
frame frame that will be written
Returns:
It returns 1 on success, 0 if not implemented, and -1 on failure.

Definition at line 2597 of file channel.c.

References ast_write(), ast_channel::tech, and ast_channel_tech::write_video.

02598 {
02599    int res;
02600    if (!chan->tech->write_video)
02601       return 0;
02602    res = ast_write(chan, fr);
02603    if (!res)
02604       res = 1;
02605    return res;
02606 }

const char* channelreloadreason2txt ( enum channelreloadreason  reason  ) 

Convert enum channelreloadreason to text string for manager event.

Parameters:
reason Enum channelreloadreason - reason for reload (manager, cli, start etc)
\ brief Convert channel reloadreason (ENUM) to text string for manager event

Definition at line 4606 of file channel.c.

References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.

Referenced by reload_config().

04607 {
04608    switch (reason) {
04609    case CHANNEL_MODULE_LOAD:
04610       return "LOAD (Channel module load)";
04611 
04612    case CHANNEL_MODULE_RELOAD:
04613       return "RELOAD (Channel module reload)";
04614 
04615    case CHANNEL_CLI_RELOAD:
04616       return "CLIRELOAD (Channel module reload by CLI command)";
04617 
04618    default:
04619       return "MANAGERRELOAD (Channel module reload by manager)";
04620    }
04621 };


Variable Documentation


Generated on Sun Jun 12 16:37:56 2011 for Asterisk - the Open Source PBX by  doxygen 1.5.6