Fri Sep 25 19:28:32 2009

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 CRASH   do { } while(0)
#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, 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, int callingpres, const char *cidnum, const char *cidname, char *uniqueid)
 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_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_sendtext (struct ast_channel *chan, const char *dest, const char *text, int ispdu)
 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_cid (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 1022 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 1018 of file channel.h.

#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)

Return all voice frames on channel 1.

Definition at line 1020 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 (  ) 

Definition at line 1369 of file channel.h.

Referenced by ast_sendtext(), ast_waitfor_nandfds(), ast_write(), phone_read(), and zt_read().

#define CRASH   do { } while(0)

#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 286 of file channel.h.

Referenced by __ast_read(), and ast_write().

#define LOAD_OH ( oh   ) 

Definition at line 529 of file channel.h.

Referenced by ast_pbx_outgoing_exten2().

#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 454 of file channel.h.

00454      {
00455    /*! \brief Channels have this property if they can accept input with jitter; 
00456     *         i.e. most VoIP channels */
00457    AST_CHAN_TP_WANTSJITTER = (1 << 0),
00458    /*! \brief Channels have this property if they can create jitter; 
00459     *         i.e. most VoIP channels */
00460    AST_CHAN_TP_CREATESJITTER = (1 << 1),
00461 };

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 464 of file channel.h.

00464      {
00465    /*! Queue incoming dtmf, to be released when this flag is turned off */
00466    AST_FLAG_DEFER_DTMF =    (1 << 1),
00467    /*! write should be interrupt generator */
00468    AST_FLAG_WRITE_INT =     (1 << 2),
00469    /*! a thread is blocking on this channel */
00470    AST_FLAG_BLOCKING =      (1 << 3),
00471    /*! This is a zombie channel */
00472    AST_FLAG_ZOMBIE =        (1 << 4),
00473    /*! There is an exception pending */
00474    AST_FLAG_EXCEPTION =     (1 << 5),
00475    /*! Listening to moh XXX anthm promises me this will disappear XXX */
00476    AST_FLAG_MOH =           (1 << 6),
00477    /*! This channel is spying on another channel */
00478    AST_FLAG_SPYING =        (1 << 7),
00479    /*! This channel is in a native bridge */
00480    AST_FLAG_NBRIDGE =       (1 << 8),
00481    /*! the channel is in an auto-incrementing dialplan processor,
00482     *  so when ->priority is set, it will get incremented before
00483     *  finding the next priority to run */
00484    AST_FLAG_IN_AUTOLOOP =   (1 << 9),
00485    /*! This is an outgoing call */
00486    AST_FLAG_OUTGOING =      (1 << 10),
00487    /*! This channel is being whispered on */
00488    AST_FLAG_WHISPER =       (1 << 11),
00489    /*! A DTMF_BEGIN frame has been read from this channel, but not yet an END */
00490    AST_FLAG_IN_DTMF =       (1 << 12),
00491    /*! A DTMF_END was received when not IN_DTMF, so the length of the digit is 
00492     *  currently being emulated */
00493    AST_FLAG_EMULATE_DTMF =  (1 << 13),
00494    /*! This is set to tell the channel not to generate DTMF begin frames, and
00495     *  to instead only generate END frames. */
00496    AST_FLAG_END_DTMF_ONLY = (1 << 14),
00497    /*! This flag indicates that on a masquerade, an active stream should not
00498     *  be carried over */
00499    AST_FLAG_MASQ_NOSTREAM = (1 << 15),
00500 };

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 503 of file channel.h.

00503      {
00504    AST_FEATURE_PLAY_WARNING = (1 << 0),
00505    AST_FEATURE_REDIRECT =     (1 << 1),
00506    AST_FEATURE_DISCONNECT =   (1 << 2),
00507    AST_FEATURE_ATXFER =       (1 << 3),
00508    AST_FEATURE_AUTOMON =      (1 << 4),
00509    AST_FEATURE_PARKCALL =     (1 << 5),
00510 };

anonymous enum

Enumerator:
AST_CDR_TRANSFER 
AST_CDR_FORWARD 
AST_CDR_CALLWAIT 
AST_CDR_CONFERENCE 

Definition at line 551 of file channel.h.

00551      {
00552    AST_CDR_TRANSFER =   (1 << 0),
00553    AST_CDR_FORWARD =    (1 << 1),
00554    AST_CDR_CALLWAIT =   (1 << 2),
00555    AST_CDR_CONFERENCE = (1 << 3),
00556 };

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 558 of file channel.h.

00558      {
00559    /*! Soft hangup by device */
00560    AST_SOFTHANGUP_DEV =       (1 << 0),
00561    /*! Soft hangup for async goto */
00562    AST_SOFTHANGUP_ASYNCGOTO = (1 << 1),
00563    AST_SOFTHANGUP_SHUTDOWN =  (1 << 2),
00564    AST_SOFTHANGUP_TIMEOUT =   (1 << 3),
00565    AST_SOFTHANGUP_APPUNLOAD = (1 << 4),
00566    AST_SOFTHANGUP_EXPLICIT =  (1 << 5),
00567    AST_SOFTHANGUP_UNBRIDGE =  (1 << 6),
00568 };

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 288 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 301 of file channel.h.

00301                        {
00302    /*! Channel is down and available */
00303    AST_STATE_DOWN,
00304    /*! Channel is down, but reserved */
00305    AST_STATE_RESERVED,
00306    /*! Channel is off hook */
00307    AST_STATE_OFFHOOK,
00308    /*! Digits (or equivalent) have been dialed */
00309    AST_STATE_DIALING,
00310    /*! Line is ringing */
00311    AST_STATE_RING,
00312    /*! Remote end is ringing */
00313    AST_STATE_RINGING,
00314    /*! Line is up */
00315    AST_STATE_UP,
00316    /*! Line is busy */
00317    AST_STATE_BUSY,
00318    /*! Digits (or equivalent) have been dialed while offhook */
00319    AST_STATE_DIALING_OFFHOOK,
00320    /*! Channel has detected an incoming call and is waiting for ring */
00321    AST_STATE_PRERING,
00322 
00323    /*! Do not transmit voice data */
00324    AST_STATE_MUTE = (1 << 16),
00325 };

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 572 of file channel.h.


Function Documentation

struct ast_channel* __ast_request_and_dial ( 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 3128 of file channel.c.

References ast_channel::_state, outgoing_helper::account, ast_call(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, 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_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, ast_channel::cid, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_callerid::cid_pres, 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_pbx_outgoing_app2(), ast_pbx_outgoing_exten2(), ast_request_and_dial(), and parkandannounce_exec().

03129 {
03130    int dummy_outstate;
03131    int cause = 0;
03132    struct ast_channel *chan;
03133    int res = 0;
03134    
03135    if (outstate)
03136       *outstate = 0;
03137    else
03138       outstate = &dummy_outstate;   /* make outstate always a valid pointer */
03139 
03140    chan = ast_request_with_uniqueid(type, format, data, &cause, uniqueid);
03141    if (!chan) {
03142       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
03143       /* compute error and return */
03144       if (cause == AST_CAUSE_BUSY)
03145          *outstate = AST_CONTROL_BUSY;
03146       else if (cause == AST_CAUSE_CONGESTION)
03147          *outstate = AST_CONTROL_CONGESTION;
03148       return NULL;
03149    }
03150 
03151    if (oh) {
03152       if (oh->vars)  
03153          ast_set_variables(chan, oh->vars);
03154       /* XXX why is this necessary, for the parent_channel perhaps ? */
03155       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
03156          ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
03157       if (oh->parent_channel)
03158          ast_channel_inherit_variables(oh->parent_channel, chan);
03159       if (oh->account)
03160          ast_cdr_setaccount(chan, oh->account); 
03161    }
03162    ast_set_callerid(chan, cid_num, cid_name, cid_num);
03163    chan->cid.cid_pres = callingpres;
03164    
03165 
03166    if (!chan->cdr) { /* up till now, this insertion hasn't been done. Therefore,
03167             to keep from throwing off the basic order of the universe,
03168             we will try to keep this cdr from getting posted. */
03169       chan->cdr = ast_cdr_alloc();
03170       ast_cdr_init(chan->cdr, chan);
03171       ast_cdr_start(chan->cdr);
03172    }
03173    if (ast_call(chan, data, 0)) {   /* ast_call failed... */
03174       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
03175    } else {
03176       res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
03177       while (timeout && chan->_state != AST_STATE_UP) {
03178          struct ast_frame *f;
03179          res = ast_waitfor(chan, timeout);
03180          if (res <= 0) /* error, timeout, or done */
03181             break;
03182          if (timeout > -1)
03183             timeout = res;
03184          f = ast_read(chan);
03185          if (!f) {
03186             *outstate = AST_CONTROL_HANGUP;
03187             res = 0;
03188             break;
03189          }
03190          if (f->frametype == AST_FRAME_CONTROL) {
03191             switch (f->subclass) {
03192             case AST_CONTROL_RINGING:  /* record but keep going */
03193                *outstate = f->subclass;
03194                break;
03195 
03196             case AST_CONTROL_BUSY:
03197             case AST_CONTROL_CONGESTION:
03198             case AST_CONTROL_ANSWER:
03199                *outstate = f->subclass;
03200                timeout = 0;      /* trick to force exit from the while() */
03201                break;
03202 
03203             /* Ignore these */
03204             case AST_CONTROL_PROGRESS:
03205             case AST_CONTROL_PROCEEDING:
03206             case AST_CONTROL_HOLD:
03207             case AST_CONTROL_UNHOLD:
03208             case AST_CONTROL_VIDUPDATE:
03209             case -1:       /* Ignore -- just stopping indications */
03210                break;
03211 
03212             default:
03213                ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
03214             }
03215          }
03216          ast_frfree(f);
03217       }
03218    }
03219 
03220    /* Final fixups */
03221    if (oh) {
03222       if (!ast_strlen_zero(oh->context))
03223          ast_copy_string(chan->context, oh->context, sizeof(chan->context));
03224       if (!ast_strlen_zero(oh->exten))
03225          ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
03226       if (oh->priority) 
03227          chan->priority = oh->priority;
03228    }
03229    if (chan->_state == AST_STATE_UP)
03230       *outstate = AST_CONTROL_ANSWER;
03231 
03232    if (res <= 0) {
03233       if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
03234          ast_cdr_init(chan->cdr, chan);
03235       if (chan->cdr) {
03236          char tmp[256];
03237          snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
03238          ast_cdr_setapp(chan->cdr,"Dial",tmp);
03239          ast_cdr_update(chan);
03240          ast_cdr_start(chan->cdr);
03241          ast_cdr_end(chan->cdr);
03242          /* If the cause wasn't handled properly */
03243          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
03244             ast_cdr_failed(chan->cdr);
03245       }
03246       ast_hangup(chan);
03247       chan = NULL;
03248    }
03249    return chan;
03250 }

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

Activate a given generator

Definition at line 1903 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(), milliwatt_exec(), and sms_exec().

01904 {
01905    int res = 0;
01906 
01907    ast_channel_lock(chan);
01908 
01909    if (chan->generatordata) {
01910       if (chan->generator && chan->generator->release)
01911          chan->generator->release(chan, chan->generatordata);
01912       chan->generatordata = NULL;
01913    }
01914 
01915    ast_prod(chan);
01916    if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
01917       res = -1;
01918    }
01919    
01920    if (!res) {
01921       ast_settimeout(chan, 160, generator_force, chan);
01922       chan->generator = gen;
01923    }
01924 
01925    ast_channel_unlock(chan);
01926 
01927    return res;
01928 }

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns number of active/allocated channels

Definition at line 462 of file channel.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and channels.

Referenced by quit_handler().

00463 {
00464    struct ast_channel *c;
00465    int cnt = 0;
00466    AST_LIST_LOCK(&channels);
00467    AST_LIST_TRAVERSE(&channels, c, chan_list)
00468       cnt++;
00469    AST_LIST_UNLOCK(&channels);
00470    return cnt;
00471 }

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 1288 of file channel.h.

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

Referenced by ast_waitfor_nandfds().

01289 {
01290    pfd->fd = fd;
01291    pfd->events = POLLIN | POLLPRI;
01292    return fd >= 0;
01293 }

char* ast_alloc_uniqueid ( void   ) 

Create a uniqueid.

Definition at line 728 of file channel.c.

References ast_config_AST_SYSTEM_NAME, ast_mainpid, malloc, and uniqueint.

Referenced by action_originate().

00728                                {
00729    char *uniqueid;
00730    uniqueid = malloc(64);
00731    if (!uniqueid) return NULL;
00732    snprintf(uniqueid, 63, "%s-%d-%li.%d", ast_config_AST_SYSTEM_NAME, ast_mainpid, (long)time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
00733    return uniqueid;
00734 }

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 1835 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(), 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(), builtin_parkcall(), common_exec(), conf_exec(), count_exec(), dictate_exec(), directory_exec(), disa_exec(), features_answer(), handle_answer(), ices_exec(), milliwatt_exec(), my_pickup_call(), my_pickup_channel(), 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().

01836 {
01837    int res = 0;
01838    ast_channel_lock(chan);
01839    /* You can't answer an outbound call */
01840    if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
01841       ast_channel_unlock(chan);
01842       return 0;
01843    }
01844    /* Stop if we're a zombie or need a soft hangup */
01845    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01846       ast_channel_unlock(chan);
01847       return -1;
01848    }
01849    switch(chan->_state) {
01850    case AST_STATE_RINGING:
01851    case AST_STATE_RING:
01852       if (chan->tech->answer)
01853          res = chan->tech->answer(chan);
01854       ast_setstate(chan, AST_STATE_UP);
01855       ast_cdr_answer(chan->cdr);
01856       break;
01857    case AST_STATE_UP:
01858       ast_cdr_answer(chan->cdr);
01859       break;
01860    default:
01861       break;
01862    }
01863    chan->visible_indication = 0;
01864    ast_channel_unlock(chan);
01865    return res;
01866 }

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 156 of file autoservice.c.

References ast_calloc, ast_channel_lock, ast_channel_unlock, AST_FLAG_END_DTMF_ONLY, 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(), system_exec_helper(), and try_calling().

00157 {
00158    int res = 0;
00159    struct asent *as;
00160 
00161    /* Check if the channel already has autoservice */
00162    AST_LIST_LOCK(&aslist);
00163    AST_LIST_TRAVERSE(&aslist, as, list) {
00164       if (as->chan == chan) {
00165          as->use_count++;
00166          break;
00167       }
00168    }
00169    AST_LIST_UNLOCK(&aslist);
00170 
00171    if (as) {
00172       /* Entry exists, autoservice is already handling this channel */
00173       return 0;
00174    }
00175 
00176    if (!(as = ast_calloc(1, sizeof(*as))))
00177       return -1;
00178    
00179    /* New entry created */
00180    as->chan = chan;
00181    as->use_count = 1;
00182 
00183    ast_channel_lock(chan);
00184    as->orig_end_dtmf_flag = ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY) ? 1 : 0;
00185    if (!as->orig_end_dtmf_flag)
00186       ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
00187    ast_channel_unlock(chan);
00188 
00189    AST_LIST_LOCK(&aslist);
00190    AST_LIST_INSERT_HEAD(&aslist, as, list);
00191    AST_LIST_UNLOCK(&aslist);
00192 
00193    if (asthread == AST_PTHREADT_NULL) { /* need start the thread */
00194       if (ast_pthread_create_background(&asthread, NULL, autoservice_run, NULL)) {
00195          ast_log(LOG_WARNING, "Unable to create autoservice thread :(\n");
00196          /* There will only be a single member in the list at this point,
00197             the one we just added. */
00198          AST_LIST_LOCK(&aslist);
00199          AST_LIST_REMOVE(&aslist, as, list);
00200          AST_LIST_UNLOCK(&aslist);
00201          free(as);
00202          res = -1;
00203       } else
00204          pthread_kill(asthread, SIGURG);
00205    }
00206 
00207    return res;
00208 }

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 210 of file autoservice.c.

References ast_channel::_softhangup, ast_clear_flag, AST_FLAG_BLOCKING, AST_FLAG_END_DTMF_ONLY, ast_frfree, AST_LIST_APPEND_LIST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, 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(), ast_test_flag, 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(), system_exec_helper(), and try_calling().

00211 {
00212    int res = -1;
00213    struct asent *as;
00214    AST_LIST_HEAD_NOLOCK(, ast_frame) dtmf_frames;
00215    struct ast_frame *f;
00216    int removed = 0;
00217    int orig_end_dtmf_flag = 0;
00218 
00219    AST_LIST_HEAD_INIT_NOLOCK(&dtmf_frames);
00220 
00221    AST_LIST_LOCK(&aslist);
00222    AST_LIST_TRAVERSE_SAFE_BEGIN(&aslist, as, list) {  
00223       if (as->chan == chan) {
00224          as->use_count--;
00225          if (as->use_count)
00226             break;
00227          AST_LIST_REMOVE_CURRENT(&aslist, list);
00228          AST_LIST_APPEND_LIST(&dtmf_frames, &as->dtmf_frames, frame_list);
00229          orig_end_dtmf_flag = as->orig_end_dtmf_flag;
00230          free(as);
00231          removed = 1;
00232          if (!chan->_softhangup)
00233             res = 0;
00234          break;
00235       }
00236    }
00237    AST_LIST_TRAVERSE_SAFE_END
00238 
00239    if (removed && asthread != AST_PTHREADT_NULL) 
00240       pthread_kill(asthread, SIGURG);
00241 
00242    AST_LIST_UNLOCK(&aslist);
00243 
00244    if (!removed)
00245       return 0;
00246 
00247    if (!orig_end_dtmf_flag)
00248       ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
00249 
00250    /* Wait for it to un-block */
00251    while (ast_test_flag(chan, AST_FLAG_BLOCKING))
00252       usleep(1000);
00253 
00254    while ((f = AST_LIST_REMOVE_HEAD(&dtmf_frames, frame_list))) {
00255       ast_queue_frame(chan, f);
00256       ast_frfree(f);
00257    }
00258 
00259    return res;
00260 }

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 449 of file channel.c.

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

Referenced by quit_handler().

00450 {
00451    struct ast_channel *c;
00452    shutting_down = 1;
00453    if (hangup) {
00454       AST_LIST_LOCK(&channels);
00455       AST_LIST_TRAVERSE(&channels, c, chan_list)
00456          ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00457       AST_LIST_UNLOCK(&channels);
00458    }
00459 }

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 674 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().

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

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 3312 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(), 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().

03313 {
03314    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
03315       If the remote end does not answer within the timeout, then do NOT hang up, but
03316       return anyway.  */
03317    int res = -1;
03318    /* Stop if we're a zombie or need a soft hangup */
03319    ast_channel_lock(chan);
03320    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03321       if (chan->tech->call)
03322          res = chan->tech->call(chan, addr, timeout);
03323       ast_set_flag(chan, AST_FLAG_OUTGOING);
03324    }
03325    ast_channel_unlock(chan);
03326    return res;
03327 }

void ast_cancel_shutdown ( void   ) 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 474 of file channel.c.

References shutting_down.

Referenced by handle_abort_halt().

00475 {
00476    shutting_down = 0;
00477 }

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 594 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().

00595 {
00596    int x;
00597 
00598    for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++) {
00599       if (causes[x].cause == cause)
00600          return causes[x].desc;
00601    }
00602 
00603    return "Unknown";
00604 }

void ast_change_name ( struct ast_channel chan,
char *  newname 
)

Change channel name.

Definition at line 3560 of file channel.c.

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

03561 {
03562    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
03563    ast_string_field_set(chan, name, newname);
03564 }

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 737 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_mainpid, 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, global_fin, global_fout, 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(), shutting_down, ast_channel::streamid, ast_channel::tech, ast_channel::timingfd, uniqueint, and ast_channel::varshead.

Referenced by __oh323_new(), acf_odbc_read(), acf_odbc_write(), 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_exten2(), 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().

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

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 4188 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_FEATURE_PLAY_WARNING, AST_FEATURE_REDIRECT, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_generic_bridge(), ast_log(), ast_set_flag, AST_SOFTHANGUP_UNBRIDGE, ast_strlen_zero(), ast_test_flag, ast_tvadd(), ast_tvsub(), ast_verbose(), 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_channel::spies, 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().

04190 {
04191    struct ast_channel *who = NULL;
04192    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
04193    int nativefailed=0;
04194    int firstpass;
04195    int o0nativeformats;
04196    int o1nativeformats;
04197    long time_left_ms=0;
04198    struct timeval nexteventts = { 0, };
04199    char caller_warning = 0;
04200    char callee_warning = 0;
04201 
04202    if (c0->_bridge) {
04203       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
04204          c0->name, c0->_bridge->name);
04205       return -1;
04206    }
04207    if (c1->_bridge) {
04208       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
04209          c1->name, c1->_bridge->name);
04210       return -1;
04211    }
04212 
04213    if (IS_DIGITAL(c0->transfercapability) || IS_DIGITAL(c1->transfercapability)) {
04214        config->flags = 0;
04215    }
04216    
04217    /* Stop if we're a zombie or need a soft hangup */
04218    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
04219        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
04220       return -1;
04221 
04222    *fo = NULL;
04223    firstpass = config->firstpass;
04224    config->firstpass = 0;
04225 
04226    if (ast_tvzero(config->start_time))
04227       config->start_time = ast_tvnow();
04228    time_left_ms = config->timelimit;
04229 
04230    caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
04231    callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
04232 
04233    if (config->start_sound && firstpass) {
04234       if (caller_warning)
04235          bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000);
04236       if (callee_warning)
04237          bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000);
04238    }
04239 
04240    /* Keep track of bridge */
04241    c0->_bridge = c1;
04242    c1->_bridge = c0;
04243 
04244    /* \todo  XXX here should check that cid_num is not NULL */
04245    manager_event(EVENT_FLAG_CALL, "Link",
04246             "Channel1: %s\r\n"
04247             "Channel2: %s\r\n"
04248             "Uniqueid1: %s\r\n"
04249             "Uniqueid2: %s\r\n"
04250             "CallerID1: %s\r\n"
04251             "CallerID2: %s\r\n",
04252             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04253 
04254    o0nativeformats = c0->nativeformats;
04255    o1nativeformats = c1->nativeformats;
04256 
04257    if (config->feature_timer) {
04258       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
04259    } else if (config->timelimit) {
04260       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
04261       if (caller_warning || callee_warning)
04262          nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000));
04263    }
04264 
04265    if (!c0->tech->send_digit_begin)
04266       ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
04267    if (!c1->tech->send_digit_begin)
04268       ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
04269 
04270    for (/* ever */;;) {
04271       struct timeval now = { 0, };
04272       int to;
04273 
04274       to = -1;
04275 
04276       if (!ast_tvzero(nexteventts)) {
04277          now = ast_tvnow();
04278          to = ast_tvdiff_ms(nexteventts, now);
04279          if (to <= 0) {
04280             if (!config->timelimit) {
04281                res = AST_BRIDGE_COMPLETE;
04282                break;
04283             }
04284             to = 0;
04285          }
04286       }
04287 
04288       if (config->timelimit) {
04289          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
04290          if (time_left_ms < to)
04291             to = time_left_ms;
04292 
04293          if (time_left_ms <= 0) {
04294             if (caller_warning && config->end_sound)
04295                bridge_playfile(c0, c1, config->end_sound, 0);
04296             if (callee_warning && config->end_sound)
04297                bridge_playfile(c1, c0, config->end_sound, 0);
04298             *fo = NULL;
04299             if (who)
04300                *rc = who;
04301             res = 0;
04302             break;
04303          }
04304          
04305          if (!to) {
04306             if (time_left_ms >= 5000 && config->warning_sound && config->play_warning) {
04307                int t = (time_left_ms + 500) / 1000; /* round to nearest second */
04308                if (caller_warning)
04309                   bridge_playfile(c0, c1, config->warning_sound, t);
04310                if (callee_warning)
04311                   bridge_playfile(c1, c0, config->warning_sound, t);
04312             }
04313             if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000)))
04314                nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
04315             else
04316                nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
04317          }
04318       }
04319 
04320       if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
04321          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04322             c0->_softhangup = 0;
04323          if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04324             c1->_softhangup = 0;
04325          c0->_bridge = c1;
04326          c1->_bridge = c0;
04327          if (option_debug)
04328             ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
04329          continue;
04330       }
04331       
04332       /* Stop if we're a zombie or need a soft hangup */
04333       if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
04334           ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
04335          *fo = NULL;
04336          if (who)
04337             *rc = who;
04338          res = 0;
04339          if (option_debug)
04340             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",
04341                c0->name, c1->name,
04342                ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
04343                ast_check_hangup(c0) ? "Yes" : "No",
04344                ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
04345                ast_check_hangup(c1) ? "Yes" : "No");
04346          break;
04347       }
04348       
04349       /* See if the BRIDGEPEER variable needs to be updated */
04350       if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER")))
04351          pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1->name);
04352       if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))
04353          pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
04354       
04355       if (c0->tech->bridge &&
04356           (config->timelimit == 0) &&
04357           (c0->tech->bridge == c1->tech->bridge) &&
04358           !nativefailed && !c0->monitor && !c1->monitor &&
04359           !c0->spies && !c1->spies && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) &&
04360           !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) &&
04361           !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
04362          /* Looks like they share a bridge method and nothing else is in the way */
04363          ast_set_flag(c0, AST_FLAG_NBRIDGE);
04364          ast_set_flag(c1, AST_FLAG_NBRIDGE);
04365          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
04366             /* \todo  XXX here should check that cid_num is not NULL */
04367             manager_event(EVENT_FLAG_CALL, "Unlink",
04368                      "Channel1: %s\r\n"
04369                      "Channel2: %s\r\n"
04370                      "Uniqueid1: %s\r\n"
04371                      "Uniqueid2: %s\r\n"
04372                      "CallerID1: %s\r\n"
04373                      "CallerID2: %s\r\n",
04374                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04375             if (option_debug)
04376                ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
04377 
04378             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
04379             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
04380 
04381             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04382                continue;
04383 
04384             c0->_bridge = NULL;
04385             c1->_bridge = NULL;
04386 
04387             return res;
04388          } else {
04389             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
04390             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
04391          }
04392          switch (res) {
04393          case AST_BRIDGE_RETRY:
04394             continue;
04395          default:
04396             if (option_verbose > 2)
04397                ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s ended\n",
04398                       c0->name, c1->name);
04399             /* fallthrough */
04400          case AST_BRIDGE_FAILED_NOWARN:
04401             nativefailed++;
04402             break;
04403          }
04404       }
04405    
04406       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
04407           (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
04408           !(c0->generator || c1->generator)) {
04409          if (ast_channel_make_compatible(c0, c1)) {
04410             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
04411             /* \todo  XXX here should check that cid_num is not NULL */
04412                                 manager_event(EVENT_FLAG_CALL, "Unlink",
04413                      "Channel1: %s\r\n"
04414                      "Channel2: %s\r\n"
04415                      "Uniqueid1: %s\r\n"
04416                      "Uniqueid2: %s\r\n"
04417                      "CallerID1: %s\r\n"
04418                      "CallerID2: %s\r\n",
04419                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04420             return AST_BRIDGE_FAILED;
04421          }
04422          o0nativeformats = c0->nativeformats;
04423          o1nativeformats = c1->nativeformats;
04424       }
04425       res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
04426       if (res != AST_BRIDGE_RETRY)
04427          break;
04428    }
04429 
04430    ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
04431    ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
04432 
04433    c0->_bridge = NULL;
04434    c1->_bridge = NULL;
04435 
04436    /* \todo  XXX here should check that cid_num is not NULL */
04437    manager_event(EVENT_FLAG_CALL, "Unlink",
04438             "Channel1: %s\r\n"
04439             "Channel2: %s\r\n"
04440             "Uniqueid1: %s\r\n"
04441             "Uniqueid2: %s\r\n"
04442             "CallerID1: %s\r\n"
04443             "CallerID2: %s\r\n",
04444             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04445    if (option_debug)
04446       ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
04447 
04448    return res;
04449 }

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 494 of file channel.c.

References ast_channel::whentohangup.

00495 {
00496    time_t whentohangup;
00497 
00498    if (chan->whentohangup == 0) {
00499       return (offset == 0) ? 0 : -1;
00500    } else {
00501       if (offset == 0)  /* XXX why is this special ? */
00502          return (1);
00503       else {
00504          whentohangup = offset + time (NULL);
00505          if (chan->whentohangup < whentohangup)
00506             return (1);
00507          else if (chan->whentohangup == whentohangup)
00508             return (0);
00509          else
00510             return (-1);
00511       }
00512    }
00513 }

int ast_channel_datastore_add ( struct ast_channel chan,
struct ast_datastore datastore 
)

Add a datastore to a channel.

Definition at line 1363 of file channel.c.

References AST_LIST_INSERT_HEAD.

Referenced by speech_create(), and try_calling().

01364 {
01365    int res = 0;
01366 
01367    AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
01368 
01369    return res;
01370 }

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

Create a channel datastore structure.

Definition at line 1302 of file channel.c.

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

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

01303 {
01304    struct ast_datastore *datastore = NULL;
01305 
01306    /* Make sure we at least have type so we can identify this */
01307    if (info == NULL) {
01308       return NULL;
01309    }
01310 
01311    /* Allocate memory for datastore and clear it */
01312    datastore = ast_calloc(1, sizeof(*datastore));
01313    if (datastore == NULL) {
01314       return NULL;
01315    }
01316 
01317    datastore->info = info;
01318 
01319    datastore->uid = ast_strdup(uid);
01320 
01321    return datastore;
01322 }

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 1390 of file channel.c.

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

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

01391 {
01392    struct ast_datastore *datastore = NULL;
01393    
01394    if (info == NULL)
01395       return NULL;
01396 
01397    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
01398       if (datastore->info == info) {
01399          if (uid != NULL && datastore->uid != NULL) {
01400             if (!strcasecmp(uid, datastore->uid)) {
01401                /* Matched by type AND uid */
01402                break;
01403             }
01404          } else {
01405             /* Matched by type at least */
01406             break;
01407          }
01408       }
01409    }
01410    AST_LIST_TRAVERSE_SAFE_END
01411 
01412    return datastore;
01413 }

int ast_channel_datastore_free ( struct ast_datastore datastore  ) 

Free a channel datastore structure.

Definition at line 1324 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(), and try_calling().

01325 {
01326    int res = 0;
01327 
01328    /* Using the destroy function (if present) destroy the data */
01329    if (datastore->info->destroy != NULL && datastore->data != NULL) {
01330       datastore->info->destroy(datastore->data);
01331       datastore->data = NULL;
01332    }
01333 
01334    /* Free allocated UID memory */
01335    if (datastore->uid != NULL) {
01336       free(datastore->uid);
01337       datastore->uid = NULL;
01338    }
01339 
01340    /* Finally free memory used by ourselves */
01341    free(datastore);
01342 
01343    return res;
01344 }

int ast_channel_datastore_inherit ( struct ast_channel from,
struct ast_channel to 
)

Inherit datastores from a parent to a child.

Definition at line 1346 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().

01347 {
01348    struct ast_datastore *datastore = NULL, *datastore2;
01349 
01350    AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
01351       if (datastore->inheritance > 0) {
01352          datastore2 = ast_channel_datastore_alloc(datastore->info, datastore->uid);
01353          if (datastore2) {
01354             datastore2->data = datastore->info->duplicate(datastore->data);
01355             datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
01356             AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
01357          }
01358       }
01359    }
01360    return 0;
01361 }

int ast_channel_datastore_remove ( struct ast_channel chan,
struct ast_datastore datastore 
)

Remove a datastore from a channel.

Definition at line 1372 of file channel.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, and AST_LIST_TRAVERSE_SAFE_END.

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

01373 {
01374    struct ast_datastore *datastore2 = NULL;
01375    int res = -1;
01376 
01377    /* Find our position and remove ourselves */
01378    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, entry) {
01379       if (datastore2 == datastore) {
01380          AST_LIST_REMOVE_CURRENT(&chan->datastores, entry);
01381          res = 0;
01382          break;
01383       }
01384    }
01385    AST_LIST_TRAVERSE_SAFE_END
01386 
01387    return res;
01388 }

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 1003 of file channel.c.

References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.

Referenced by __adsi_transmit_messages(), and find_cache().

01004 {
01005    int pre = 0;
01006 
01007    if (chan) {
01008       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
01009       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
01010    }
01011    return pre;
01012 }

void ast_channel_free ( struct ast_channel  ) 

Free a channel structure.

Definition at line 1215 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_channel_whisper_stop(), ast_device_state_changed_literal(), ast_frfree, ast_jb_destroy(), AST_LIST_HEAD_INIT_NOLOCK, 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, ast_channel::whisper, and ast_channel::writetrans.

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

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

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 3566 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(), agent_call(), ast_feature_request_and_dial(), begin_dial(), findmeexec(), ring_entry(), and wait_for_answer().

03567 {
03568    struct ast_var_t *current, *newvar;
03569    const char *varname;
03570 
03571    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
03572       int vartype = 0;
03573 
03574       varname = ast_var_full_name(current);
03575       if (!varname)
03576          continue;
03577 
03578       if (varname[0] == '_') {
03579          vartype = 1;
03580          if (varname[1] == '_')
03581             vartype = 2;
03582       }
03583 
03584       switch (vartype) {
03585       case 1:
03586          newvar = ast_var_assign(&varname[1], ast_var_value(current));
03587          if (newvar) {
03588             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03589             if (option_debug)
03590                ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
03591          }
03592          break;
03593       case 2:
03594          newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
03595          if (newvar) {
03596             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03597             if (option_debug)
03598                ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
03599          }
03600          break;
03601       default:
03602          if (option_debug)
03603             ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
03604          break;
03605       }
03606    }
03607 }

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 3419 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 app_exec(), ast_channel_bridge(), ast_retrieve_call(), autoanswer_exec(), check_compat(), park_exec(), try_calling(), and wait_for_answer().

03420 {
03421    int src;
03422    int dst;
03423 
03424    if (chan->readformat == peer->writeformat && chan->writeformat == peer->readformat) {
03425       /* Already compatible!  Moving on ... */
03426       return 0;
03427    }
03428 
03429    /* Set up translation from the chan to the peer */
03430    src = chan->nativeformats;
03431    dst = peer->nativeformats;
03432    if (ast_translator_best_choice(&dst, &src) < 0) {
03433       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
03434       return -1;
03435    }
03436 
03437    /* if the best path is not 'pass through', then
03438       transcoding is needed; if desired, force transcode path
03439       to use SLINEAR between channels, but only if there is
03440       no direct conversion available */
03441    if ((src != dst) && ast_opt_transcode_via_slin &&
03442        (ast_translate_path_steps(dst, src) != 1))
03443       dst = AST_FORMAT_SLINEAR;
03444    if (ast_set_read_format(chan, dst) < 0) {
03445       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
03446       return -1;
03447    }
03448    if (ast_set_write_format(peer, dst) < 0) {
03449       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst);
03450       return -1;
03451    }
03452 
03453    /* Set up translation from the peer to the chan */
03454    src = peer->nativeformats;
03455    dst = chan->nativeformats;
03456    if (ast_translator_best_choice(&dst, &src) < 0) {
03457       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst);
03458       return -1;
03459    }
03460 
03461    /* if the best path is not 'pass through', then
03462       transcoding is needed; if desired, force transcode path
03463       to use SLINEAR between channels, but only if there is
03464       no direct conversion available */
03465    if ((src != dst) && ast_opt_transcode_via_slin &&
03466        (ast_translate_path_steps(dst, src) != 1))
03467       dst = AST_FORMAT_SLINEAR;
03468    if (ast_set_read_format(peer, dst) < 0) {
03469       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst);
03470       return -1;
03471    }
03472    if (ast_set_write_format(chan, dst) < 0) {
03473       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst);
03474       return -1;
03475    }
03476    return 0;
03477 }

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 3479 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(), handle_invite_replaces(), iax_park(), misdn_transfer_bc(), my_pickup_call(), my_pickup_channel(), pickup_do(), and sip_park().

03480 {
03481    int res = -1;
03482    struct ast_channel *final_orig, *final_clone, *base;
03483 
03484 retrymasq:
03485    final_orig = original;
03486    final_clone = clone;
03487 
03488    ast_channel_lock(original);
03489    while (ast_channel_trylock(clone)) {
03490       ast_channel_unlock(original);
03491       usleep(1);
03492       ast_channel_lock(original);
03493    }
03494 
03495    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
03496       and if so, we don't really want to masquerade it, but its proxy */
03497    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
03498       final_orig = original->_bridge;
03499 
03500    if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone))
03501       final_clone = clone->_bridge;
03502    
03503    if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) {
03504       final_clone = base;
03505    }
03506 
03507    if ((final_orig != original) || (final_clone != clone)) {
03508       /* Lots and lots of deadlock avoidance.  The main one we're competing with
03509        * is ast_write(), which locks channels recursively, when working with a
03510        * proxy channel. */
03511       if (ast_channel_trylock(final_orig)) {
03512          ast_channel_unlock(clone);
03513          ast_channel_unlock(original);
03514          goto retrymasq;
03515       }
03516       if (ast_channel_trylock(final_clone)) {
03517          ast_channel_unlock(final_orig);
03518          ast_channel_unlock(clone);
03519          ast_channel_unlock(original);
03520          goto retrymasq;
03521       }
03522       ast_channel_unlock(clone);
03523       ast_channel_unlock(original);
03524       original = final_orig;
03525       clone = final_clone;
03526    }
03527 
03528    if (original == clone) {
03529       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
03530       ast_channel_unlock(clone);
03531       ast_channel_unlock(original);
03532       return -1;
03533    }
03534 
03535    if (option_debug)
03536       ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
03537          clone->name, original->name);
03538    if (original->masq) {
03539       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03540          original->masq->name, original->name);
03541    } else if (clone->masqr) {
03542       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03543          clone->name, clone->masqr->name);
03544    } else {
03545       original->masq = clone;
03546       clone->masqr = original;
03547       ast_queue_frame(original, &ast_null_frame);
03548       ast_queue_frame(clone, &ast_null_frame);
03549       if (option_debug)
03550          ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
03551       res = 0;
03552    }
03553 
03554    ast_channel_unlock(clone);
03555    ast_channel_unlock(original);
03556 
03557    return res;
03558 }

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 3105 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().

03106 {
03107    switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */
03108    {
03109    case 0:
03110       return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
03111    case AST_CONTROL_HANGUP:
03112       return "Hangup";
03113    case AST_CONTROL_RING:
03114       return "Local Ring";
03115    case AST_CONTROL_RINGING:
03116       return "Remote end Ringing";
03117    case AST_CONTROL_ANSWER:
03118       return "Remote end has Answered";
03119    case AST_CONTROL_BUSY:
03120       return "Remote end is Busy";
03121    case AST_CONTROL_CONGESTION:
03122       return "Congestion (circuits busy)";
03123    default:
03124       return "Unknown Reason!!";
03125    }
03126 }

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 516 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().

00517 {
00518    struct chanlist *chan;
00519 
00520    AST_LIST_LOCK(&channels);
00521 
00522    AST_LIST_TRAVERSE(&backends, chan, list) {
00523       if (!strcasecmp(tech->type, chan->tech->type)) {
00524          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00525          AST_LIST_UNLOCK(&channels);
00526          return -1;
00527       }
00528    }
00529    
00530    if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00531       AST_LIST_UNLOCK(&channels);
00532       return -1;
00533    }
00534    chan->tech = tech;
00535    AST_LIST_INSERT_HEAD(&backends, chan, list);
00536 
00537    if (option_debug)
00538       ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00539 
00540    if (option_verbose > 1)
00541       ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type,
00542              chan->tech->description);
00543 
00544    AST_LIST_UNLOCK(&channels);
00545    return 0;
00546 }

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 3407 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().

03408 {
03409    if (chan->tech->send_html)
03410       return chan->tech->send_html(chan, subclass, data, datalen);
03411    return -1;
03412 }

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 3414 of file channel.c.

References ast_channel_sendhtml(), and AST_HTML_URL.

Referenced by sendurl_exec(), and try_calling().

03415 {
03416    return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
03417 }

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 4452 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(), set_volume(), try_calling(), vm_forwardoptions(), and zt_hangup().

04453 {
04454    int res;
04455 
04456    if (chan->tech->setoption) {
04457       res = chan->tech->setoption(chan, option, data, datalen);
04458       if (res < 0)
04459          return res;
04460    } else {
04461       errno = ENOSYS;
04462       return -1;
04463    }
04464    if (block) {
04465       /* XXX Implement blocking -- just wait for our option frame reply, discarding
04466          intermediate packets. XXX */
04467       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
04468       return -1;
04469    }
04470    return 0;
04471 }

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 486 of file channel.c.

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

Referenced by action_timeout(), and timeout_write().

00487 {
00488    chan->whentohangup = offset ? time(NULL) + offset : 0;
00489    ast_queue_frame(chan, &ast_null_frame);
00490    return;
00491 }

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 4903 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(), channel_spy(), and record_exec().

04904 {
04905    struct ast_silence_generator *state;
04906 
04907    if (!(state = ast_calloc(1, sizeof(*state)))) {
04908       return NULL;
04909    }
04910 
04911    state->old_write_format = chan->writeformat;
04912 
04913    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
04914       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
04915       free(state);
04916       return NULL;
04917    }
04918 
04919    ast_activate_generator(chan, &silence_generator, state);
04920 
04921    if (option_debug)
04922       ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
04923 
04924    return state;
04925 }

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 4927 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(), channel_spy(), and record_exec().

04928 {
04929    if (!state)
04930       return;
04931 
04932    ast_deactivate_generator(chan);
04933 
04934    if (option_debug)
04935       ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
04936 
04937    if (ast_set_write_format(chan, state->old_write_format) < 0)
04938       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
04939 
04940    free(state);
04941 }

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 3402 of file channel.c.

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

Referenced by sendurl_exec(), and try_calling().

03403 {
03404    return (chan->tech->send_html) ? 1 : 0;
03405 }

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 1015 of file channel.c.

References ast_clear_flag, and AST_FLAG_DEFER_DTMF.

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

01016 {
01017    if (chan)
01018       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
01019 }

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 548 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().

00549 {
00550    struct chanlist *chan;
00551 
00552    if (option_debug)
00553       ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
00554 
00555    AST_LIST_LOCK(&channels);
00556 
00557    AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00558       if (chan->tech == tech) {
00559          AST_LIST_REMOVE_CURRENT(&backends, list);
00560          free(chan);
00561          if (option_verbose > 1)
00562             ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
00563          break;   
00564       }
00565    }
00566    AST_LIST_TRAVERSE_SAFE_END
00567 
00568    AST_LIST_UNLOCK(&channels);
00569 }

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 1131 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().

01132 {
01133    return channel_find_locked(prev, NULL, 0, NULL, NULL, NULL);
01134 }

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

Definition at line 5160 of file channel.c.

References ast_mutex_lock(), ast_mutex_unlock(), ast_slinfactory_feed(), ast_channel_whisper_buffer::lock, ast_channel_whisper_buffer::sf, and ast_channel::whisper.

Referenced by channel_spy().

05161 {
05162    if (!chan->whisper)
05163       return -1;
05164 
05165    ast_mutex_lock(&chan->whisper->lock);
05166    ast_slinfactory_feed(&chan->whisper->sf, f);
05167    ast_mutex_unlock(&chan->whisper->lock);
05168 
05169    return 0;
05170 }

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.

Definition at line 5145 of file channel.c.

References ast_calloc, AST_FLAG_WHISPER, ast_mutex_init(), ast_set_flag, ast_slinfactory_init(), ast_channel_whisper_buffer::lock, ast_channel_whisper_buffer::sf, and ast_channel::whisper.

Referenced by channel_spy().

05146 {
05147    if (chan->whisper)
05148       return -1;
05149 
05150    if (!(chan->whisper = ast_calloc(1, sizeof(*chan->whisper))))
05151       return -1;
05152 
05153    ast_mutex_init(&chan->whisper->lock);
05154    ast_slinfactory_init(&chan->whisper->sf);
05155    ast_set_flag(chan, AST_FLAG_WHISPER);
05156 
05157    return 0;
05158 }

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.

Definition at line 5172 of file channel.c.

References ast_clear_flag, AST_FLAG_WHISPER, AST_FORMAT_SLINEAR, ast_mutex_destroy(), ast_set_write_format(), ast_slinfactory_destroy(), ast_translator_free_path(), free, ast_channel_whisper_buffer::lock, ast_channel_whisper_buffer::original_format, ast_channel_whisper_buffer::path, ast_channel_whisper_buffer::sf, ast_channel::whisper, and ast_channel::writeformat.

Referenced by ast_channel_free(), ast_do_masquerade(), and channel_spy().

05173 {
05174    if (!chan->whisper)
05175       return;
05176 
05177    ast_clear_flag(chan, AST_FLAG_WHISPER);
05178    if (chan->whisper->path)
05179       ast_translator_free_path(chan->whisper->path);
05180    if (chan->whisper->original_format && chan->writeformat == AST_FORMAT_SLINEAR)
05181       ast_set_write_format(chan, chan->whisper->original_format);
05182    ast_slinfactory_destroy(&chan->whisper->sf);
05183    ast_mutex_destroy(&chan->whisper->lock);
05184    free(chan->whisper);
05185    chan->whisper = NULL;
05186 }

struct ast_variable* ast_channeltype_list ( void   )  [read]

return an ast_variable list of channeltypes

Definition at line 182 of file channel.c.

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

00183 {
00184    struct chanlist *cl;
00185    struct ast_variable *var=NULL, *prev = NULL;
00186    AST_LIST_TRAVERSE(&backends, cl, list) {
00187       if (prev)  {
00188          if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description)))
00189             prev = prev->next;
00190       } else {
00191          var = ast_variable_new(cl->tech->type, cl->tech->description);
00192          prev = var;
00193       }
00194    }
00195    return var;
00196 }

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 404 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_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_feature_request_and_dial(), ast_indicate_data(), ast_readstring_full(), ast_recvtext(), ast_sendtext(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), ast_write(), bridge_native_loop(), bridge_p2p_loop(), builtin_atxfer(), channel_spy(), common_exec(), conf_run(), deadagi_exec(), handle_sendimage(), iax2_bridge(), pbx_exec(), rpt(), rpt_exec(), wait_for_answer(), zt_setoption(), and zt_tdd_sendtext().

00405 {
00406    if (chan->_softhangup)     /* yes if soft hangup flag set */
00407       return 1;
00408    if (!chan->tech_pvt)    /* yes if no technology private data */
00409       return 1;
00410    if (!chan->whentohangup)   /* no if no hangup scheduled */
00411       return 0;
00412    if (chan->whentohangup > time(NULL))   /* no if hangup time has not come yet. */
00413       return 0;
00414    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */
00415    return 1;
00416 }

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 3640 of file channel.c.

References ast_channel::_softhangup, ast_channel::_state, ast_channel::adsicpe, ast_channel::alertpipe, ast_app_group_update(), ast_cause2str(), ast_channel_free(), ast_channel_lock, ast_channel_unlock, ast_channel_whisper_stop(), ast_clear_flag, ast_copy_flags, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_WHISPER, 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_mutex_lock(), ast_mutex_unlock(), 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_channel_spy::chan, ast_channel::cid, clone_variables(), EVENT_FLAG_CALL, ast_channel::fdno, ast_channel::fds, ast_channel_tech::fixup, free_translation(), ast_channel_tech::hangup, ast_channel::hangupcause, language, ast_channel_spy::lock, 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, ast_channel::spies, t, ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel_tech::type, ast_channel::visible_indication, ast_channel::whisper, and ast_channel::writeformat.

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

03641 {
03642    int x,i;
03643    int res=0;
03644    int origstate;
03645    struct ast_frame *cur;
03646    const struct ast_channel_tech *t;
03647    void *t_pvt;
03648    struct ast_callerid tmpcid;
03649    struct ast_channel *clone = original->masq;
03650    struct ast_channel_spy_list *spy_list = NULL;
03651    struct ast_channel_spy *spy = NULL;
03652    struct ast_cdr *cdr;
03653    int rformat = original->readformat;
03654    int wformat = original->writeformat;
03655    char newn[100];
03656    char orig[100];
03657    char masqn[100];
03658    char zombn[100];
03659 
03660    if (option_debug > 3)
03661       ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
03662          clone->name, clone->_state, original->name, original->_state);
03663 
03664    /* XXX This is a seriously wacked out operation.  We're essentially putting the guts of
03665       the clone channel into the original channel.  Start by killing off the original
03666       channel's backend.   I'm not sure we're going to keep this function, because
03667       while the features are nice, the cost is very high in terms of pure nastiness. XXX */
03668 
03669    /* We need the clone's lock, too */
03670    ast_channel_lock(clone);
03671 
03672    if (option_debug > 1)
03673       ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock);
03674 
03675    /* Having remembered the original read/write formats, we turn off any translation on either
03676       one */
03677    free_translation(clone);
03678    free_translation(original);
03679 
03680 
03681    /* Unlink the masquerade */
03682    original->masq = NULL;
03683    clone->masqr = NULL;
03684    
03685    /* Save the original name */
03686    ast_copy_string(orig, original->name, sizeof(orig));
03687    /* Save the new name */
03688    ast_copy_string(newn, clone->name, sizeof(newn));
03689    /* Create the masq name */
03690    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
03691       
03692    /* Copy the name from the clone channel */
03693    ast_string_field_set(original, name, newn);
03694 
03695    /* Mangle the name of the clone channel */
03696    ast_string_field_set(clone, name, masqn);
03697    
03698    /* Notify any managers of the change, first the masq then the other */
03699    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\nNewUniqueid: %s\r\n", newn, masqn, clone->uniqueid, original->uniqueid);
03700    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
03701 
03702    /* Swap the technologies */   
03703    t = original->tech;
03704    original->tech = clone->tech;
03705    clone->tech = t;
03706 
03707    /* Swap the cdrs */
03708    cdr = original->cdr;
03709    original->cdr = clone->cdr;
03710    clone->cdr = cdr;
03711 
03712    t_pvt = original->tech_pvt;
03713    original->tech_pvt = clone->tech_pvt;
03714    clone->tech_pvt = t_pvt;
03715 
03716    /* Swap the alertpipes */
03717    for (i = 0; i < 2; i++) {
03718       x = original->alertpipe[i];
03719       original->alertpipe[i] = clone->alertpipe[i];
03720       clone->alertpipe[i] = x;
03721    }
03722 
03723    /* 
03724     * Swap the readq's.  The end result should be this:
03725     *
03726     *  1) All frames should be on the new (original) channel.
03727     *  2) Any frames that were already on the new channel before this
03728     *     masquerade need to be at the end of the readq, after all of the
03729     *     frames on the old (clone) channel.
03730     *  3) The alertpipe needs to get poked for every frame that was already
03731     *     on the new channel, since we are now using the alert pipe from the
03732     *     old (clone) channel.
03733     */
03734    {
03735       AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
03736       AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
03737 
03738       AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
03739       AST_LIST_APPEND_LIST(&original->readq, &clone->readq, frame_list);
03740 
03741       while ((cur = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
03742          AST_LIST_INSERT_TAIL(&original->readq, cur, frame_list);
03743          if (original->alertpipe[1] > -1) {
03744             int poke = 0;
03745             write(original->alertpipe[1], &poke, sizeof(poke));
03746          }
03747       }
03748    }
03749 
03750    /* Swap the raw formats */
03751    x = original->rawreadformat;
03752    original->rawreadformat = clone->rawreadformat;
03753    clone->rawreadformat = x;
03754    x = original->rawwriteformat;
03755    original->rawwriteformat = clone->rawwriteformat;
03756    clone->rawwriteformat = x;
03757 
03758    /* Swap the spies */
03759    spy_list = original->spies;
03760    original->spies = clone->spies;
03761    clone->spies = spy_list;
03762 
03763    /* Update channel on respective spy lists if present */
03764    if (original->spies) {
03765       AST_LIST_TRAVERSE(&original->spies->list, spy, list) {
03766          ast_mutex_lock(&spy->lock);
03767          spy->chan = original;
03768          ast_mutex_unlock(&spy->lock);
03769       }
03770    }
03771    if (clone->spies) {
03772       AST_LIST_TRAVERSE(&clone->spies->list, spy, list) {
03773          ast_mutex_lock(&spy->lock);
03774          spy->chan = clone;
03775          ast_mutex_unlock(&spy->lock);
03776       }
03777    }
03778 
03779    clone->_softhangup = AST_SOFTHANGUP_DEV;
03780 
03781    /* And of course, so does our current state.  Note we need not
03782       call ast_setstate since the event manager doesn't really consider
03783       these separate.  We do this early so that the clone has the proper
03784       state of the original channel. */
03785    origstate = original->_state;
03786    original->_state = clone->_state;
03787    clone->_state = origstate;
03788 
03789    if (clone->tech->fixup){
03790       res = clone->tech->fixup(original, clone);
03791       if (res)
03792          ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
03793    }
03794 
03795    /* Start by disconnecting the original's physical side */
03796    if (clone->tech->hangup)
03797       res = clone->tech->hangup(clone);
03798    if (res) {
03799       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
03800       ast_channel_unlock(clone);
03801       return -1;
03802    }
03803    
03804    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
03805    /* Mangle the name of the clone channel */
03806    ast_string_field_set(clone, name, zombn);
03807    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid);
03808 
03809    /* Update the type. */
03810    t_pvt = original->monitor;
03811    original->monitor = clone->monitor;
03812    clone->monitor = t_pvt;
03813    
03814    /* Keep the same language.  */
03815    ast_string_field_set(original, language, clone->language);
03816    /* Copy the FD's other than the generator fd */
03817    for (x = 0; x < AST_MAX_FDS; x++) {
03818       if (x != AST_GENERATOR_FD)
03819          original->fds[x] = clone->fds[x];
03820    }
03821 
03822    ast_app_group_update(clone, original);
03823 
03824    /* move any whisperer over */
03825    ast_channel_whisper_stop(original);
03826    if (ast_test_flag(clone, AST_FLAG_WHISPER)) {
03827       original->whisper = clone->whisper;
03828       ast_set_flag(original, AST_FLAG_WHISPER);
03829       clone->whisper = NULL;
03830       ast_clear_flag(clone, AST_FLAG_WHISPER);
03831    }
03832 
03833    /* Move data stores over */
03834    if (AST_LIST_FIRST(&clone->datastores))
03835       AST_LIST_APPEND_LIST(&original->datastores, &clone->datastores, entry);
03836 
03837    clone_variables(original, clone);
03838    /* Presense of ADSI capable CPE follows clone */
03839    original->adsicpe = clone->adsicpe;
03840    /* Bridge remains the same */
03841    /* CDR fields remain the same */
03842    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
03843    /* Application and data remain the same */
03844    /* Clone exception  becomes real one, as with fdno */
03845    ast_copy_flags(original, clone, AST_FLAG_EXCEPTION);
03846    original->fdno = clone->fdno;
03847    /* Schedule context remains the same */
03848    /* Stream stuff stays the same */
03849    /* Keep the original state.  The fixup code will need to work with it most likely */
03850 
03851    /* Just swap the whole structures, nevermind the allocations, they'll work themselves
03852       out. */
03853    tmpcid = original->cid;
03854    original->cid = clone->cid;
03855    clone->cid = tmpcid;
03856    
03857    /* Restore original timing file descriptor */
03858    original->fds[AST_TIMING_FD] = original->timingfd;
03859    
03860    /* Our native formats are different now */
03861    original->nativeformats = clone->nativeformats;
03862    
03863    /* Context, extension, priority, app data, jump table,  remain the same */
03864    /* pvt switches.  pbx stays the same, as does next */
03865    
03866    /* Set the write format */
03867    ast_set_write_format(original, wformat);
03868 
03869    /* Set the read format */
03870    ast_set_read_format(original, rformat);
03871 
03872    /* Copy the music class */
03873    ast_string_field_set(original, musicclass, clone->musicclass);
03874 
03875    if (option_debug)
03876       ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
03877 
03878    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
03879       can fix up everything as best as possible */
03880    if (original->tech->fixup) {
03881       res = original->tech->fixup(clone, original);
03882       if (res) {
03883          ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
03884             original->tech->type, original->name);
03885          ast_channel_unlock(clone);
03886          return -1;
03887       }
03888    } else
03889       ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
03890          original->tech->type, original->name);
03891 
03892    /* If an indication is currently playing maintain it on the channel that is taking the place of original */
03893    if (original->visible_indication)
03894       ast_indicate(original, original->visible_indication);
03895    
03896    /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
03897       a zombie so nothing tries to touch it.  If it's already been marked as a
03898       zombie, then free it now (since it already is considered invalid). */
03899    if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) {
03900       if (option_debug)
03901          ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name);
03902       ast_channel_unlock(clone);
03903       manager_event(EVENT_FLAG_CALL, "Hangup",
03904          "Channel: %s\r\n"
03905          "Uniqueid: %s\r\n"
03906          "Cause: %d\r\n"
03907          "Cause-txt: %s\r\n",
03908          clone->name,
03909          clone->uniqueid,
03910          clone->hangupcause,
03911          ast_cause2str(clone->hangupcause)
03912          );
03913       ast_channel_free(clone);
03914    } else {
03915       if (option_debug)
03916          ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
03917       ast_set_flag(clone, AST_FLAG_ZOMBIE);
03918       ast_queue_frame(clone, &ast_null_frame);
03919       ast_channel_unlock(clone);
03920    }
03921    
03922    /* Signal any blocker */
03923    if (ast_test_flag(original, AST_FLAG_BLOCKING))
03924       pthread_kill(original->blocker, SIGURG);
03925    if (option_debug)
03926       ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state);
03927    return 0;
03928 }

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 1296 of file channel.h.

References pollfd::revents.

Referenced by do_monitor().

01297 {
01298    int x;
01299    int dummy=0;
01300 
01301    if (fd < 0)
01302       return 0;
01303    if (!start)
01304       start = &dummy;
01305    for (x = *start; x<max; x++)
01306       if (pfds[x].fd == fd) {
01307          if (x == *start)
01308             (*start)++;
01309          return pfds[x].revents;
01310       }
01311    return 0;
01312 }

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 1156 of file channel.c.

References channel_find_locked().

01157 {
01158    return channel_find_locked(NULL, NULL, 0, context, exten, NULL);
01159 }

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 1143 of file channel.c.

References channel_find_locked().

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

01144 {
01145    return channel_find_locked(NULL, name, namelen, NULL, NULL, NULL);
01146 }

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

Get channel by uniqueid (locks channel)

Definition at line 1168 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().

01169 {
01170    return channel_find_locked(NULL, NULL, 0, NULL, NULL, uniqueid);
01171 }

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 571 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().

00572 {
00573    struct chanlist *chanls;
00574    const struct ast_channel_tech *ret = NULL;
00575 
00576    if (AST_LIST_LOCK(&channels)) {
00577       ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
00578       return NULL;
00579    }
00580 
00581    AST_LIST_TRAVERSE(&backends, chanls, list) {
00582       if (!strcasecmp(name, chanls->tech->type)) {
00583          ret = chanls->tech;
00584          break;
00585       }
00586    }
00587 
00588    AST_LIST_UNLOCK(&channels);
00589    
00590    return ret;
00591 }

ast_group_t ast_get_group ( const char *  s  ) 

Definition at line 4625 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().

04626 {
04627    char *piece;
04628    char *c;
04629    int start=0, finish=0, x;
04630    ast_group_t group = 0;
04631 
04632    if (ast_strlen_zero(s))
04633       return 0;
04634 
04635    c = ast_strdupa(s);
04636    
04637    while ((piece = strsep(&c, ","))) {
04638       if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
04639          /* Range */
04640       } else if (sscanf(piece, "%d", &start)) {
04641          /* Just one */
04642          finish = start;
04643       } else {
04644          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
04645          continue;
04646       }
04647       for (x = start; x <= finish; x++) {
04648          if ((x > 63) || (x < 0)) {
04649             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
04650          } else
04651             group |= ((ast_group_t) 1 << x);
04652       }
04653    }
04654    return group;
04655 }

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 1745 of file channel.c.

References 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::blocker, ast_channel::blockproc, ast_channel::cdr, CRASH, detach_spies(), 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(), __oh323_new(), 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_app2(), ast_pbx_outgoing_exten2(), ast_pbx_run_app(), ast_retrieve_call(), ast_retrieve_call_to_death(), ast_send_message(), async_wait(), autoanswer_exec(), begin_dial(), 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().

01746 {
01747    int res = 0;
01748    struct ast_cdr *cdr = NULL;
01749 
01750    /* Don't actually hang up a channel that will masquerade as someone else, or
01751       if someone is going to masquerade as us */
01752    ast_channel_lock(chan);
01753 
01754    detach_spies(chan);     /* get rid of spies */
01755 
01756    ast_autoservice_stop(chan);
01757 
01758    if (chan->masq) {
01759       if (ast_do_masquerade(chan))
01760          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01761    }
01762 
01763    if (chan->masq) {
01764       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
01765       ast_channel_unlock(chan);
01766       return 0;
01767    }
01768    /* If this channel is one which will be masqueraded into something,
01769       mark it as a zombie already, so we know to free it later */
01770    if (chan->masqr) {
01771       ast_set_flag(chan, AST_FLAG_ZOMBIE);
01772       ast_channel_unlock(chan);
01773       return 0;
01774    }
01775    free_translation(chan);
01776    /* Close audio stream */
01777    if (chan->stream) {
01778       ast_closestream(chan->stream);
01779       chan->stream = NULL;
01780    }
01781    /* Close video stream */
01782    if (chan->vstream) {
01783       ast_closestream(chan->vstream);
01784       chan->vstream = NULL;
01785    }
01786    if (chan->sched) {
01787       sched_context_destroy(chan->sched);
01788       chan->sched = NULL;
01789    }
01790    
01791    if (chan->generatordata)   /* Clear any tone stuff remaining */
01792       chan->generator->release(chan, chan->generatordata);
01793    chan->generatordata = NULL;
01794    chan->generator = NULL;
01795    if (chan->cdr) {     /* End the CDR if it hasn't already */
01796       ast_cdr_end(chan->cdr);
01797       cdr = chan->cdr;
01798       chan->cdr = NULL;
01799    }
01800    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01801       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
01802                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
01803                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
01804       CRASH;
01805    }
01806    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
01807       if (option_debug)
01808          ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
01809       if (chan->tech->hangup)
01810          res = chan->tech->hangup(chan);
01811    } else {
01812       if (option_debug)
01813          ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
01814    }
01815          
01816    ast_channel_unlock(chan);
01817    manager_event(EVENT_FLAG_CALL, "Hangup",
01818          "Channel: %s\r\n"
01819          "Uniqueid: %s\r\n"
01820          "Cause: %d\r\n"
01821          "Cause-txt: %s\r\n",
01822          chan->name,
01823          chan->uniqueid,
01824          chan->hangupcause,
01825          ast_cause2str(chan->hangupcause)
01826          );
01827    ast_channel_free(chan);
01828 
01829    if (cdr)
01830       ast_cdr_detach(cdr);
01831 
01832    return res;
01833 }

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 2612 of file channel.c.

References ast_indicate_data().

Referenced by __ast_play_and_record(), agent_new(), ast_bridge_call(), 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().

02613 {
02614    return ast_indicate_data(chan, condition, NULL, 0);
02615 }

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 2617 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_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().

02618 {
02619    int res = -1;
02620 
02621    ast_channel_lock(chan);
02622    /* Stop if we're a zombie or need a soft hangup */
02623    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02624       ast_channel_unlock(chan);
02625       return -1;
02626    }
02627    if (chan->tech->indicate)
02628       res = chan->tech->indicate(chan, condition, data, datalen);
02629    ast_channel_unlock(chan);
02630    if (!chan->tech->indicate || res) {
02631       /*
02632        * Device does not support (that) indication, lets fake
02633        * it by doing our own tone generation. (PM2002)
02634        */
02635       if (condition < 0)
02636          ast_playtones_stop(chan);
02637       else {
02638          const struct tone_zone_sound *ts = NULL;
02639          switch (condition) {
02640          case AST_CONTROL_RINGING:
02641             ts = ast_get_indication_tone(chan->zone, "ring");
02642             break;
02643          case AST_CONTROL_BUSY:
02644             ts = ast_get_indication_tone(chan->zone, "busy");
02645             break;
02646          case AST_CONTROL_CONGESTION:
02647             ts = ast_get_indication_tone(chan->zone, "congestion");
02648             break;
02649          }
02650          if (ts && ts->data[0]) {
02651             if (option_debug)
02652                ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
02653             ast_playtones_start(chan,0,ts->data, 1);
02654             res = 0;
02655             chan->visible_indication = condition;
02656          } else if (condition == AST_CONTROL_PROGRESS) {
02657             /* ast_playtones_stop(chan); */
02658          } else if (condition == AST_CONTROL_PROCEEDING) {
02659             /* Do nothing, really */
02660          } else if (condition == AST_CONTROL_HOLD) {
02661             /* Do nothing.... */
02662          } else if (condition == AST_CONTROL_UNHOLD) {
02663             /* Do nothing.... */
02664          } else if (condition == AST_CONTROL_VIDUPDATE) {
02665             /* Do nothing.... */
02666          } else {
02667             /* not handled */
02668             ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
02669             res = -1;
02670          }
02671       }
02672    } else
02673       chan->visible_indication = condition;
02674 
02675    return res;
02676 }

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 2594 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().

02595 {
02596    int ret = ast_opt_internal_timing && chan->timingfd > -1;
02597    if (option_debug > 4)
02598       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);
02599    return ret;
02600 }

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

print call- and pickup groups into buffer

Definition at line 4710 of file channel.c.

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

04711 {
04712    unsigned int i;
04713    int first=1;
04714    char num[3];
04715 
04716    buf[0] = '\0';
04717    
04718    if (!group) /* Return empty string if no group */
04719       return buf;
04720 
04721    for (i = 0; i <= 63; i++) {   /* Max group is 63 */
04722       if (group & ((ast_group_t) 1 << i)) {
04723             if (!first) {
04724             strncat(buf, ", ", buflen);
04725          } else {
04726             first=0;
04727          }
04728          snprintf(num, sizeof(num), "%u", i);
04729          strncat(buf, num, buflen);
04730       }
04731    }
04732    return buf;
04733 }

int ast_prod ( struct ast_channel chan  ) 

Send empty audio to prime a channel driver.

Definition at line 2798 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().

02799 {
02800    struct ast_frame a = { AST_FRAME_VOICE };
02801    char nothing[128];
02802 
02803    /* Send an empty audio frame to get things moving */
02804    if (chan->_state != AST_STATE_UP) {
02805       if (option_debug)
02806          ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
02807       a.subclass = chan->rawwriteformat;
02808       a.data = nothing + AST_FRIENDLY_OFFSET;
02809       a.src = "ast_prod";
02810       if (ast_write(chan, &a))
02811          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
02812    }
02813    return 0;
02814 }

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 990 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().

00992 {
00993    struct ast_frame f = { AST_FRAME_CONTROL, };
00994 
00995    f.subclass = control;
00996    f.data = (void *) data;
00997    f.datalen = datalen;
00998 
00999    return ast_queue_frame(chan, &f);
01000 }

int ast_queue_frame ( struct ast_channel chan,
struct ast_frame fin 
)

Queue an outgoing frame.

Definition at line 912 of file channel.c.

References ast_channel::alertpipe, 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, CRASH, 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().

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

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 2602 of file channel.c.

References __ast_read().

Referenced by __adsi_transmit_messages(), __ast_play_and_record(), __ast_request_and_dial(), 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().

02603 {
02604    return __ast_read(chan, 0);
02605 }

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 2607 of file channel.c.

References __ast_read().

Referenced by conf_run().

02608 {
02609    return __ast_read(chan, 1);
02610 }

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 3354 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().

03355 {
03356    return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
03357 }

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 3359 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().

03360 {
03361    int pos = 0;   /* index in the buffer where we accumulate digits */
03362    int to = ftimeout;
03363 
03364    /* Stop if we're a zombie or need a soft hangup */
03365    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03366       return -1;
03367    if (!len)
03368       return -1;
03369    for (;;) {
03370       int d;
03371       if (c->stream) {
03372          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
03373          ast_stopstream(c);
03374          usleep(1000);
03375          if (!d)
03376             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03377       } else {
03378          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03379       }
03380       if (d < 0)
03381          return -1;
03382       if (d == 0) {
03383          s[pos]='\0';
03384          return 1;
03385       }
03386       if (d == 1) {
03387          s[pos]='\0';
03388          return 2;
03389       }
03390       if (!strchr(enders, d))
03391          s[pos++] = d;
03392       if (strchr(enders, d) || (pos >= len)) {
03393          s[pos]='\0';
03394          return 0;
03395       }
03396       to = timeout;
03397    }
03398    /* Never reached */
03399    return 0;
03400 }

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 2678 of file channel.c.

References ast_recvtext(), and free.

Referenced by handle_recvchar().

02679 {
02680    int c;
02681    char *buf = ast_recvtext(chan, timeout);
02682    if (buf == NULL)
02683       return -1;  /* error or timeout */
02684    c = *(unsigned char *)buf;
02685    free(buf);
02686    return c;
02687 }

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 2689 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().

02690 {
02691    int res, done = 0;
02692    char *buf = NULL;
02693    
02694    while (!done) {
02695       struct ast_frame *f;
02696       if (ast_check_hangup(chan))
02697          break;
02698       res = ast_waitfor(chan, timeout);
02699       if (res <= 0) /* timeout or error */
02700          break;
02701       timeout = res; /* update timeout */
02702       f = ast_read(chan);
02703       if (f == NULL)
02704          break; /* no frame */
02705       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
02706          done = 1;   /* force a break */
02707       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
02708          buf = ast_strndup((char *) f->data, f->datalen);   /* dup and break */
02709          done = 1;
02710       }
02711       ast_frfree(f);
02712    }
02713    return buf;
02714 }

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 3307 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().

03308 {
03309     return ast_request_with_uniqueid(type, format, data, cause, NULL);
03310 }

struct ast_channel* ast_request_and_dial ( const char *  type,
int  format,
void *  data,
int  timeout,
int *  reason,
int  callingpres,
const char *  cidnum,
const char *  cidname,
char *  uniqueid 
) [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 3252 of file channel.c.

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_exten2().

03253 {
03254    return __ast_request_and_dial(type, format, data, timeout, outstate, 0, cidnum, cidname, NULL, uniqueid);
03255 }

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 3257 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(), and ast_request().

03258 {
03259    struct chanlist *chan;
03260    struct ast_channel *c;
03261    int capabilities;
03262    int fmt;
03263    int res;
03264    int foo;
03265    int videoformat = format & AST_FORMAT_VIDEO_MASK;
03266 
03267    if (!cause)
03268       cause = &foo;
03269    *cause = AST_CAUSE_NOTDEFINED;
03270 
03271    if (AST_LIST_LOCK(&channels)) {
03272       ast_log(LOG_WARNING, "Unable to lock channel list\n");
03273       return NULL;
03274    }
03275 
03276    AST_LIST_TRAVERSE(&backends, chan, list) {
03277       if (strcasecmp(type, chan->tech->type))
03278          continue;
03279 
03280       capabilities = chan->tech->capabilities;
03281       fmt = format & AST_FORMAT_AUDIO_MASK;
03282       res = ast_translator_best_choice(&fmt, &capabilities);
03283       if (res < 0) {
03284          ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
03285          *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03286          AST_LIST_UNLOCK(&channels);
03287          return NULL;
03288       }
03289       AST_LIST_UNLOCK(&channels);
03290       if (!chan->tech->requester)
03291          return NULL;
03292       
03293       if (!(c = chan->tech->requester(type, capabilities | videoformat, data, cause)))
03294          return NULL;
03295 
03296       /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
03297       return c;
03298    }
03299 
03300    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
03301    *cause = AST_CAUSE_NOSUCHDRIVER;
03302    AST_LIST_UNLOCK(&channels);
03303 
03304    return NULL;
03305 }

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 1195 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(), 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().

01196 {
01197    return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
01198 }

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 1174 of file channel.c.

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

Referenced by __login_exec(), and ast_safe_sleep().

01175 {
01176    struct ast_frame *f;
01177 
01178    while (ms > 0) {
01179       if (cond && ((*cond)(data) == 0))
01180          return 0;
01181       ms = ast_waitfor(chan, ms);
01182       if (ms < 0)
01183          return -1;
01184       if (ms > 0) {
01185          f = ast_read(chan);
01186          if (!f)
01187             return -1;
01188          ast_frfree(f);
01189       }
01190    }
01191    return 0;
01192 }

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 428 of file channel.c.

References ast_malloc, and len.

Referenced by features_new(), and zt_new().

00429 {
00430    char *b2, buf[1];
00431    int len;
00432    va_list args;
00433 
00434    va_start(args, fmt);
00435    len = vsnprintf(buf, 1, fmt, args);
00436    va_end(args);
00437 
00438    if (!(b2 = ast_malloc(len + 1)))
00439       return NULL;
00440 
00441    va_start(args, fmt);
00442    vsnprintf(b2, len + 1,  fmt, args);
00443    va_end(args);
00444 
00445    return b2;
00446 }

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 1337 of file channel.h.

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

01338 {
01339 #ifdef __linux__
01340    return select(nfds, rfds, wfds, efds, tvp);
01341 #else
01342    if (tvp) {
01343       struct timeval tv, tvstart, tvend, tvlen;
01344       int res;
01345 
01346       tv = *tvp;
01347       gettimeofday(&tvstart, NULL);
01348       res = select(nfds, rfds, wfds, efds, tvp);
01349       gettimeofday(&tvend, NULL);
01350       timersub(&tvend, &tvstart, &tvlen);
01351       timersub(&tv, &tvlen, tvp);
01352       if (tvp->tv_sec < 0 || (tvp->tv_sec == 0 && tvp->tv_usec < 0)) {
01353          tvp->tv_sec = 0;
01354          tvp->tv_usec = 0;
01355       }
01356       return res;
01357    }
01358    else
01359       return select(nfds, rfds, wfds, efds, NULL);
01360 #endif
01361 }

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 4944 of file channel.c.

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

Referenced by action_message(), and attempt_thread().

04944                                                                                                    {
04945    struct ast_channel *chan = NULL;
04946    int status;
04947    int res = -1;
04948 
04949    chan = ast_request(type, AST_FORMAT_SLINEAR, data, &status);
04950    if (chan) {
04951        if (from) {
04952       ast_set_callerid(chan, from, from, from);
04953        }
04954        res = ast_sendtext(chan, to, message, ispdu);
04955        /* XXX what about message CDRs ??? XXX */
04956        ast_hangup(chan);
04957        return res;
04958    }
04959 
04960    return res;
04961 }

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 2788 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().

02789 {
02790    if (chan->tech->send_digit_begin) {
02791       ast_senddigit_begin(chan, digit);
02792       ast_safe_sleep(chan, AST_DEFAULT_EMULATE_DTMF_DURATION);
02793    }
02794    
02795    return ast_senddigit_end(chan, digit, AST_DEFAULT_EMULATE_DTMF_DURATION);
02796 }

int ast_senddigit_begin ( struct ast_channel chan,
char  digit 
)

Definition at line 2729 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().

02730 {
02731    /* Device does not support DTMF tones, lets fake
02732     * it by doing our own generation. */
02733    static const char* dtmf_tones[] = {
02734       "941+1336", /* 0 */
02735       "697+1209", /* 1 */
02736       "697+1336", /* 2 */
02737       "697+1477", /* 3 */
02738       "770+1209", /* 4 */
02739       "770+1336", /* 5 */
02740       "770+1477", /* 6 */
02741       "852+1209", /* 7 */
02742       "852+1336", /* 8 */
02743       "852+1477", /* 9 */
02744       "697+1633", /* A */
02745       "770+1633", /* B */
02746       "852+1633", /* C */
02747       "941+1633", /* D */
02748       "941+1209", /* * */
02749       "941+1477"  /* # */
02750    };
02751 
02752    if (!chan->tech->send_digit_begin)
02753       return 0;
02754 
02755    if (!chan->tech->send_digit_begin(chan, digit))
02756       return 0;
02757 
02758    if (digit >= '0' && digit <='9')
02759       ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
02760    else if (digit >= 'A' && digit <= 'D')
02761       ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
02762    else if (digit == '*')
02763       ast_playtones_start(chan, 0, dtmf_tones[14], 0);
02764    else if (digit == '#')
02765       ast_playtones_start(chan, 0, dtmf_tones[15], 0);
02766    else {
02767       /* not handled */
02768       if (option_debug)
02769          ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
02770    }
02771 
02772    return 0;
02773 }

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

Definition at line 2775 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().

02776 {
02777    int res = -1;
02778 
02779    if (chan->tech->send_digit_end)
02780       res = chan->tech->send_digit_end(chan, digit, duration);
02781 
02782    if (res && chan->generator)
02783       ast_playtones_stop(chan);
02784    
02785    return 0;
02786 }

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

Sends text 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 2716 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(), ast_send_message(), handle_sendtext(), and sendtext_exec().

02717 {
02718    int res = 0;
02719    /* Stop if we're a zombie or need a soft hangup */
02720    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02721       return -1;
02722    CHECK_BLOCKING(chan);
02723    if (chan->tech->send_text)
02724       res = chan->tech->send_text(chan, dest, text, ispdu);
02725    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02726    return res;
02727 }

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 3930 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(), 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().

03931 {
03932    ast_channel_lock(chan);
03933 
03934    if (callerid) {
03935       if (chan->cid.cid_num)
03936          free(chan->cid.cid_num);
03937       chan->cid.cid_num = ast_strdup(callerid);
03938    }
03939    if (calleridname) {
03940       if (chan->cid.cid_name)
03941          free(chan->cid.cid_name);
03942       chan->cid.cid_name = ast_strdup(calleridname);
03943    }
03944    if (ani) {
03945       if (chan->cid.cid_ani)
03946          free(chan->cid.cid_ani);
03947       chan->cid.cid_ani = ast_strdup(ani);
03948    }
03949    if (chan->cdr)
03950       ast_cdr_setcid(chan->cdr, chan);
03951    manager_event(EVENT_FLAG_CALL, "Newcallerid",
03952             "Channel: %s\r\n"
03953             "CallerID: %s\r\n"
03954             "CallerIDName: %s\r\n"
03955             "Uniqueid: %s\r\n"
03956             "CID-CallingPres: %d (%s)\r\n",
03957             chan->name,
03958             S_OR(chan->cid.cid_num, "<Unknown>"),
03959             S_OR(chan->cid.cid_name, "<Unknown>"),
03960             chan->uniqueid,
03961             chan->cid.cid_pres,
03962             ast_describe_caller_presentation(chan->cid.cid_pres)
03963             );
03964    
03965    ast_channel_unlock(chan);
03966 }

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 4735 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(), ast_pbx_outgoing_app2(), and ast_pbx_outgoing_exten2().

04736 {
04737    struct ast_variable *cur;
04738 
04739    for (cur = vars; cur; cur = cur->next)
04740       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
04741 }

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_cid ( 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 3968 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().

03969 {
03970    int oldstate = chan->_state;
03971 
03972    if (oldstate == state)
03973       return 0;
03974 
03975    chan->_state = state;
03976    ast_device_state_changed_literal(chan->name, cid_num, cid_name);
03977    /* setstate used to conditionally report Newchannel; this is no more */
03978    manager_event(EVENT_FLAG_CALL,
03979             "Newstate",
03980             "Channel: %s\r\n"
03981             "State: %s\r\n"
03982             "CallerID: %s\r\n"
03983             "CallerIDName: %s\r\n"
03984             "Uniqueid: %s\r\n",
03985             chan->name, ast_state2str(chan->_state),
03986             S_OR(chan->cid.cid_num, "<unknown>"),
03987             S_OR(chan->cid.cid_name, "<unknown>"),
03988             chan->uniqueid);
03989 
03990    return 0;
03991 }

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

Definition at line 2107 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().

02108 {
02109    int res = -1;
02110 #ifdef HAVE_ZAPTEL
02111    if (c->timingfd > -1) {
02112       if (!func) {
02113          samples = 0;
02114          data = 0;
02115       }
02116       if (option_debug)
02117          ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
02118       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
02119       c->timingfunc = func;
02120       c->timingdata = data;
02121    }
02122 #endif   
02123    return res;
02124 }

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 480 of file channel.c.

References shutting_down.

Referenced by handle_request_options().

00481 {
00482    return shutting_down;
00483 }

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 1600 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().

01601 {
01602    int res;
01603    ast_channel_lock(chan);
01604    res = ast_softhangup_nolock(chan, cause);
01605    ast_channel_unlock(chan);
01606    return res;
01607 }

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 1586 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().

01587 {
01588    if (option_debug)
01589       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
01590    /* Inform channel driver that we need to be hung up, if it cares */
01591    chan->_softhangup |= cause;
01592    ast_queue_frame(chan, &ast_null_frame);
01593    /* Interrupt any poll call or such */
01594    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
01595       pthread_kill(chan->blocker, SIGURG);
01596    return 0;
01597 }

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 619 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_cid(), 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().

00620 {
00621    char *buf;
00622 
00623    switch(state) {
00624    case AST_STATE_DOWN:
00625       return "Down";
00626    case AST_STATE_RESERVED:
00627       return "Rsrvd";
00628    case AST_STATE_OFFHOOK:
00629       return "OffHook";
00630    case AST_STATE_DIALING:
00631       return "Dialing";
00632    case AST_STATE_RING:
00633       return "Ring";
00634    case AST_STATE_RINGING:
00635       return "Ringing";
00636    case AST_STATE_UP:
00637       return "Up";
00638    case AST_STATE_BUSY:
00639       return "Busy";
00640    case AST_STATE_DIALING_OFFHOOK:
00641       return "Dialing Offhook";
00642    case AST_STATE_PRERING:
00643       return "Pre-ring";
00644    default:
00645       if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE)))
00646          return "Unknown";
00647       snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state);
00648       return buf;
00649    }
00650 }

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 607 of file channel.c.

References causes.

Referenced by pbx_builtin_hangup().

00608 {
00609    int x;
00610 
00611    for (x = 0; x < sizeof(causes) / sizeof(causes[0]); x++)
00612       if (strncasecmp(causes[x].name, name, strlen(causes[x].name)) == 0)
00613          return causes[x].cause;
00614 
00615    return -1;
00616 }

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 4607 of file channel.c.

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

Referenced by zapateller_exec().

04608 {
04609    int res;
04610 
04611    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
04612       return res;
04613 
04614    /* Give us some wiggle room */
04615    while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
04616       struct ast_frame *f = ast_read(chan);
04617       if (f)
04618          ast_frfree(f);
04619       else
04620          return -1;
04621    }
04622    return 0;
04623 }

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

Start a tone going

Definition at line 4589 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().

04590 {
04591    struct tonepair_def d = { 0, };
04592 
04593    d.freq1 = freq1;
04594    d.freq2 = freq2;
04595    d.duration = duration;
04596    d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */
04597    if (ast_activate_generator(chan, &tonepair, &d))
04598       return -1;
04599    return 0;
04600 }

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 4602 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

04603 {
04604    ast_deactivate_generator(chan);
04605 }

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 3336 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().

03337 {
03338    int res = -1;
03339 
03340    /* Stop if we're a zombie or need a soft hangup */
03341    ast_channel_lock(chan);
03342    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03343       if (chan->tech->transfer) {
03344          res = chan->tech->transfer(chan, dest);
03345          if (!res)
03346             res = 1;
03347       } else
03348          res = 0;
03349    }
03350    ast_channel_unlock(chan);
03351    return res;
03352 }

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 653 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().

00654 {
00655    switch(transfercapability) {
00656    case AST_TRANS_CAP_SPEECH:
00657       return "SPEECH";
00658    case AST_TRANS_CAP_DIGITAL:
00659       return "DIGITAL";
00660    case AST_TRANS_CAP_RESTRICTED_DIGITAL:
00661       return "RESTRICTED_DIGITAL";
00662    case AST_TRANS_CAP_3_1K_AUDIO:
00663       return "3K1AUDIO";
00664    case AST_TRANS_CAP_DIGITAL_W_TONES:
00665       return "DIGITAL_W_TONES";
00666    case AST_TRANS_CAP_VIDEO:
00667       return "VIDEO";
00668    default:
00669       return "UNKNOWN";
00670    }
00671 }

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 2091 of file channel.c.

References ast_waitfor_nandfds().

Referenced by __adsi_transmit_messages(), __ast_play_and_record(), __ast_request_and_dial(), 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().

02092 {
02093    int oldms = ms;   /* -1 if no timeout */
02094 
02095    ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
02096    if ((ms < 0) && (oldms < 0))
02097       ms = 0;
02098    return ms;
02099 }

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 2086 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().

02087 {
02088    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
02089 }

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 1931 of file channel.c.

References ast_waitfor_nandfds().

Referenced by dundi_lookup_internal(), and dundi_precache_internal().

01932 {
01933    int winner = -1;
01934    ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
01935    return winner;
01936 }

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 1939 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().

01941 {
01942    struct timeval start = { 0 , 0 };
01943    struct pollfd *pfds;
01944    int res;
01945    long rms;
01946    int x, y, max;
01947    int sz;
01948    time_t now = 0;
01949    long whentohangup = 0, diff;
01950    struct ast_channel *winner = NULL;
01951    struct fdmap {
01952       int chan;
01953       int fdno;
01954    } *fdmap;
01955 
01956    sz = n * AST_MAX_FDS + nfds;
01957    pfds = alloca(sizeof(*pfds) * sz);
01958    fdmap = alloca(sizeof(*fdmap) * sz);
01959 
01960    if (outfd)
01961       *outfd = -99999;
01962    if (exception)
01963       *exception = 0;
01964    
01965    /* Perform any pending masquerades */
01966    for (x=0; x < n; x++) {
01967       ast_channel_lock(c[x]);
01968       if (c[x]->masq) {
01969          if (ast_do_masquerade(c[x])) {
01970             ast_log(LOG_WARNING, "Masquerade failed\n");
01971             *ms = -1;
01972             ast_channel_unlock(c[x]);
01973             return NULL;
01974          }
01975       }
01976       if (c[x]->whentohangup) {
01977          if (!whentohangup)
01978             time(&now);
01979          diff = c[x]->whentohangup - now;
01980          if (diff < 1) {
01981             /* Should already be hungup */
01982             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
01983             ast_channel_unlock(c[x]);
01984             return c[x];
01985          }
01986          if (!whentohangup || (diff < whentohangup))
01987             whentohangup = diff;
01988       }
01989       ast_channel_unlock(c[x]);
01990    }
01991    /* Wait full interval */
01992    rms = *ms;
01993    if (whentohangup) {
01994       rms = whentohangup * 1000;              /* timeout in milliseconds */
01995       if (*ms >= 0 && *ms < rms)    /* original *ms still smaller */
01996          rms =  *ms;
01997    }
01998    /*
01999     * Build the pollfd array, putting the channels' fds first,
02000     * followed by individual fds. Order is important because
02001     * individual fd's must have priority over channel fds.
02002     */
02003    max = 0;
02004    for (x=0; x<n; x++) {
02005       for (y=0; y<AST_MAX_FDS; y++) {
02006          fdmap[max].fdno = y;  /* fd y is linked to this pfds */
02007          fdmap[max].chan = x;  /* channel x is linked to this pfds */
02008          max += ast_add_fd(&pfds[max], c[x]->fds[y]);
02009       }
02010       CHECK_BLOCKING(c[x]);
02011    }
02012    /* Add the individual fds */
02013    for (x=0; x<nfds; x++) {
02014       fdmap[max].chan = -1;
02015       max += ast_add_fd(&pfds[max], fds[x]);
02016    }
02017 
02018    if (*ms > 0)
02019       start = ast_tvnow();
02020    
02021    if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */
02022       do {
02023          int kbrms = rms;
02024          if (kbrms > 600000)
02025             kbrms = 600000;
02026          res = poll(pfds, max, kbrms);
02027          if (!res)
02028             rms -= kbrms;
02029       } while (!res && (rms > 0));
02030    } else {
02031       res = poll(pfds, max, rms);
02032    }
02033    for (x=0; x<n; x++)
02034       ast_clear_flag(c[x], AST_FLAG_BLOCKING);
02035    if (res < 0) { /* Simulate a timeout if we were interrupted */
02036       if (errno != EINTR)
02037          *ms = -1;
02038       return NULL;
02039    }
02040    if (whentohangup) {   /* if we have a timeout, check who expired */
02041       time(&now);
02042       for (x=0; x<n; x++) {
02043          if (c[x]->whentohangup && now >= c[x]->whentohangup) {
02044             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
02045             if (winner == NULL)
02046                winner = c[x];
02047          }
02048       }
02049    }
02050    if (res == 0) { /* no fd ready, reset timeout and done */
02051       *ms = 0; /* XXX use 0 since we may not have an exact timeout. */
02052       return winner;
02053    }
02054    /*
02055     * Then check if any channel or fd has a pending event.
02056     * Remember to check channels first and fds last, as they
02057     * must have priority on setting 'winner'
02058     */
02059    for (x = 0; x < max; x++) {
02060       res = pfds[x].revents;
02061       if (res == 0)
02062          continue;
02063       if (fdmap[x].chan >= 0) {  /* this is a channel */
02064          winner = c[fdmap[x].chan]; /* override previous winners */
02065          if (res & POLLPRI)
02066             ast_set_flag(winner, AST_FLAG_EXCEPTION);
02067          else
02068             ast_clear_flag(winner, AST_FLAG_EXCEPTION);
02069          winner->fdno = fdmap[x].fdno;
02070       } else {       /* this is an fd */
02071          if (outfd)
02072             *outfd = pfds[x].fd;
02073          if (exception)
02074             *exception = (res & POLLPRI) ? -1 : 0;
02075          winner = NULL;
02076       }
02077    }
02078    if (*ms > 0) {
02079       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
02080       if (*ms < 0)
02081          *ms = 0;
02082    }
02083    return winner;
02084 }

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 2126 of file channel.c.

References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, 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().

02127 {
02128    /* Stop if we're a zombie or need a soft hangup */
02129    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
02130       return -1;
02131 
02132    /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */
02133    ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
02134 
02135    /* Wait for a digit, no more than ms milliseconds total. */
02136    while (ms) {
02137       struct ast_channel *rchan;
02138       int outfd;
02139 
02140       errno = 0;
02141       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
02142       if (!rchan && outfd < 0 && ms) {
02143          if (errno == 0 || errno == EINTR)
02144             continue;
02145          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
02146          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02147          return -1;
02148       } else if (outfd > -1) {
02149          /* The FD we were watching has something waiting */
02150          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02151          return 1;
02152       } else if (rchan) {
02153          int res;
02154          struct ast_frame *f = ast_read(c);
02155          if (!f)
02156             return -1;
02157 
02158          switch(f->frametype) {
02159          case AST_FRAME_DTMF_BEGIN:
02160             break;
02161          case AST_FRAME_DTMF_END:
02162             res = f->subclass;
02163             ast_frfree(f);
02164             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02165             return res;
02166          case AST_FRAME_CONTROL:
02167             switch(f->subclass) {
02168             case AST_CONTROL_HANGUP:
02169                ast_frfree(f);
02170                ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02171                return -1;
02172             case AST_CONTROL_RINGING:
02173             case AST_CONTROL_ANSWER:
02174                /* Unimportant */
02175                break;
02176             default:
02177                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
02178                break;
02179             }
02180             break;
02181          case AST_FRAME_VOICE:
02182             /* Write audio if appropriate */
02183             if (audiofd > -1)
02184                write(audiofd, f->data, f->datalen);
02185          default:
02186             /* Ignore */
02187             break;
02188          }
02189          ast_frfree(f);
02190       }
02191    }
02192 
02193    ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02194 
02195    return 0; /* Time is up */
02196 }

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 1162 of file channel.c.

References channel_find_locked().

Referenced by next_channel().

01164 {
01165    return channel_find_locked(chan, NULL, 0, context, exten, NULL);
01166 }

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 1149 of file channel.c.

References channel_find_locked().

Referenced by next_channel().

01151 {
01152    return channel_find_locked(chan, name, namelen, NULL, NULL, NULL);
01153 }

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 2827 of file channel.c.

References ast_channel::_softhangup, 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_WHISPER, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, AST_FORMAT_SLINEAR, ast_frame_adjust_volume(), 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_slinear_sum(), AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_log(), AST_MONITOR_RUNNING, ast_mutex_lock(), ast_mutex_unlock(), ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), ast_set_write_format(), ast_slinfactory_available(), ast_slinfactory_read(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_writestream(), 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, ast_channel_whisper_buffer::lock, LOG_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, option_debug, ast_channel_whisper_buffer::original_format, ast_channel::outsmpl, ast_channel_whisper_buffer::path, queue_frame_to_spies(), ast_channel::rawwriteformat, ast_frame::samples, SEEK_FORCECUR, ast_channel_tech::send_html, ast_channel_tech::send_text, ast_channel_whisper_buffer::sf, ast_channel::spies, SPY_WRITE, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel::whisper, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_video, ast_channel::writeformat, 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().

02828 {
02829    int res = -1;
02830    int count = 0;
02831    struct ast_frame *f = NULL;
02832 
02833    /*Deadlock avoidance*/
02834    while(ast_channel_trylock(chan)) {
02835       /*cannot goto done since the channel is not locked*/
02836       if(count++ > 10) {
02837          if(option_debug)
02838             ast_log(LOG_DEBUG, "Deadlock avoided for write to channel '%s'\n", chan->name);
02839          return 0;
02840       }
02841       usleep(1);
02842    }
02843    /* Stop if we're a zombie or need a soft hangup */
02844    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02845       goto done;
02846 
02847    /* Handle any pending masquerades */
02848    if (chan->masq && ast_do_masquerade(chan)) {
02849       ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02850       goto done;
02851    }
02852    if (chan->masqr) {
02853       res = 0; /* XXX explain, why 0 ? */
02854       goto done;
02855    }
02856    if (chan->generatordata) {
02857       if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
02858          ast_deactivate_generator(chan);
02859       else {
02860          if (fr->frametype == AST_FRAME_DTMF_END) {
02861             /* There is a generator running while we're in the middle of a digit.
02862              * It's probably inband DTMF, so go ahead and pass it so it can
02863              * stop the generator */
02864             ast_clear_flag(chan, AST_FLAG_BLOCKING);
02865             ast_channel_unlock(chan);
02866             res = ast_senddigit_end(chan, fr->subclass, fr->len);
02867             ast_channel_lock(chan);
02868             CHECK_BLOCKING(chan);
02869          } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass == AST_CONTROL_UNHOLD) {
02870             /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */
02871             res = (chan->tech->indicate == NULL) ? 0 :
02872                chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
02873          }
02874          res = 0; /* XXX explain, why 0 ? */
02875          goto done;
02876       }
02877    }
02878    /* High bit prints debugging */
02879    if (chan->fout & DEBUGCHAN_FLAG)
02880       ast_frame_dump(chan->name, fr, ">>");
02881    CHECK_BLOCKING(chan);
02882    switch(fr->frametype) {
02883    case AST_FRAME_CONTROL:
02884       res = (chan->tech->indicate == NULL) ? 0 :
02885          chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
02886       break;
02887    case AST_FRAME_DTMF_BEGIN:
02888       ast_clear_flag(chan, AST_FLAG_BLOCKING);
02889       ast_channel_unlock(chan);
02890       res = ast_senddigit_begin(chan, fr->subclass);
02891       ast_channel_lock(chan);
02892       CHECK_BLOCKING(chan);
02893       break;
02894    case AST_FRAME_DTMF_END:
02895       ast_clear_flag(chan, AST_FLAG_BLOCKING);
02896       ast_channel_unlock(chan);
02897       res = ast_senddigit_end(chan, fr->subclass, fr->len);
02898       ast_channel_lock(chan);
02899       CHECK_BLOCKING(chan);
02900       break;
02901    case AST_FRAME_TEXT:
02902       res = (chan->tech->send_text == NULL) ? 0 :
02903          chan->tech->send_text(chan, NULL, (char *) fr->data, 0);
02904       break;
02905    case AST_FRAME_HTML:
02906       res = (chan->tech->send_html == NULL) ? 0 :
02907          chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
02908       break;
02909    case AST_FRAME_VIDEO:
02910       /* XXX Handle translation of video codecs one day XXX */
02911       res = (chan->tech->write_video == NULL) ? 0 :
02912          chan->tech->write_video(chan, fr);
02913       break;
02914    case AST_FRAME_MODEM:
02915       res = (chan->tech->write == NULL) ? 0 :
02916          chan->tech->write(chan, fr);
02917       break;
02918    case AST_FRAME_VOICE:
02919       if (chan->tech->write == NULL)
02920          break;   /*! \todo XXX should return 0 maybe ? */
02921 
02922       /* If someone is whispering on this channel then we must ensure that we are always getting signed linear frames */
02923       if (ast_test_flag(chan, AST_FLAG_WHISPER)) {
02924          if (fr->subclass == AST_FORMAT_SLINEAR)
02925             f = fr;
02926          else {
02927             ast_mutex_lock(&chan->whisper->lock);
02928             if (chan->writeformat != AST_FORMAT_SLINEAR) {
02929                /* Rebuild the translation path and set our write format back to signed linear */
02930                chan->whisper->original_format = chan->writeformat;
02931                ast_set_write_format(chan, AST_FORMAT_SLINEAR);
02932                if (chan->whisper->path)
02933                   ast_translator_free_path(chan->whisper->path);
02934                chan->whisper->path = ast_translator_build_path(AST_FORMAT_SLINEAR, chan->whisper->original_format);
02935             }
02936             /* Translate frame using the above translation path */
02937             f = (chan->whisper->path) ? ast_translate(chan->whisper->path, fr, 0) : fr;
02938             ast_mutex_unlock(&chan->whisper->lock);
02939          }
02940       } else {
02941          /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
02942          if (fr->subclass == chan->rawwriteformat)
02943             f = fr;
02944          else
02945             f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
02946       }
02947 
02948       /* If we have no frame of audio, then we have to bail out */
02949       if (f == NULL) {
02950          res = 0;
02951          break;
02952       }
02953 
02954       /* If spies are on the channel then queue the frame out to them */
02955       if (chan->spies)
02956          queue_frame_to_spies(chan, f, SPY_WRITE);
02957 
02958       /* If Monitor is running on this channel, then we have to write frames out there too */
02959       if (chan->monitor && chan->monitor->write_stream) {
02960          /* XXX must explain this code */
02961 #ifndef MONITOR_CONSTANT_DELAY
02962          int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
02963          if (jump >= 0) {
02964             jump = chan->insmpl - chan->outsmpl;
02965             if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
02966                ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02967             chan->outsmpl += jump + f->samples;
02968          } else
02969             chan->outsmpl += f->samples;
02970 #else
02971          int jump = chan->insmpl - chan->outsmpl;
02972          if (jump - MONITOR_DELAY >= 0) {
02973             if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02974                ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02975             chan->outsmpl += jump;
02976          } else
02977             chan->outsmpl += f->samples;
02978 #endif
02979          if (chan->monitor->state == AST_MONITOR_RUNNING) {
02980             if (ast_writestream(chan->monitor->write_stream, f) < 0)
02981                ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
02982          }
02983       }
02984 
02985       /* Finally the good part! Write this out to the channel */
02986       if (ast_test_flag(chan, AST_FLAG_WHISPER)) {
02987          /* frame is assumed to be in SLINEAR, since that is
02988             required for whisper mode */
02989          ast_frame_adjust_volume(f, -2);
02990          if (ast_slinfactory_available(&chan->whisper->sf) >= f->samples) {
02991             short buf[f->samples];
02992             struct ast_frame whisper = {
02993                .frametype = AST_FRAME_VOICE,
02994                .subclass = AST_FORMAT_SLINEAR,
02995                .data = buf,
02996                .datalen = sizeof(buf),
02997                .samples = f->samples,
02998             };
02999             
03000             ast_mutex_lock(&chan->whisper->lock);
03001             if (ast_slinfactory_read(&chan->whisper->sf, buf, f->samples))
03002                ast_frame_slinear_sum(f, &whisper);
03003             ast_mutex_unlock(&chan->whisper->lock);
03004          }
03005          /* and now put it through the regular translator */
03006          f = (chan->writetrans) ? ast_translate(chan->writetrans, f, 0) : f;
03007       }
03008       if (f) 
03009          res = chan->tech->write(chan,f);
03010       else
03011          res = 0;
03012       break;
03013    case AST_FRAME_NULL:
03014    case AST_FRAME_IAX:
03015       /* Ignore these */
03016       res = 0;
03017       break;
03018    default:
03019       /* At this point, fr is the incoming frame and f is NULL.  Channels do
03020        * not expect to get NULL as a frame pointer and will segfault.  Hence,
03021        * we output the original frame passed in. */
03022       res = chan->tech->write(chan, fr);
03023       break;
03024    }
03025 
03026    if (f && f != fr)
03027       ast_frfree(f);
03028    ast_clear_flag(chan, AST_FLAG_BLOCKING);
03029    /* Consider a write failure to force a soft hangup */
03030    if (res < 0)
03031       chan->_softhangup |= AST_SOFTHANGUP_DEV;
03032    else {
03033       chan->fout = FRAMECOUNT_INC(chan->fout);
03034    }
03035 done:
03036    ast_channel_unlock(chan);
03037    return res;
03038 }

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 2816 of file channel.c.

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

02817 {
02818    int res;
02819    if (!chan->tech->write_video)
02820       return 0;
02821    res = ast_write(chan, fr);
02822    if (!res)
02823       res = 1;
02824    return res;
02825 }

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 4964 of file channel.c.

References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.

Referenced by reload_config().

04965 {
04966    switch (reason) {
04967    case CHANNEL_MODULE_LOAD:
04968       return "LOAD (Channel module load)";
04969 
04970    case CHANNEL_MODULE_RELOAD:
04971       return "RELOAD (Channel module reload)";
04972 
04973    case CHANNEL_CLI_RELOAD:
04974       return "CLIRELOAD (Channel module reload by CLI command)";
04975 
04976    default:
04977       return "MANAGERRELOAD (Channel module reload by manager)";
04978    }
04979 };


Variable Documentation


Generated on Fri Sep 25 19:28:33 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.5