Sat Aug 6 00:39:53 2011

Asterisk developer's documentation


channel.h File Reference

General Asterisk PBX channel definitions. More...

#include "asterisk/abstract_jb.h"
#include <unistd.h>
#include "asterisk/poll-compat.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"

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_chan_write_info_t
 Structure to handle passing func_channel_write info to channels via setoption. 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::datastores
 Data stores on the channel. 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_CHAN_WRITE_INFO_T_VERSION   1
 ast_chan_write_info_t version. Must be incremented if structure is changed
#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_TIMING_FD   (AST_MAX_FDS-2)
#define CHECK_BLOCKING(c)
#define DATASTORE_INHERIT_FOREVER   INT_MAX
#define DEBUGCHAN_FLAG   0x80000000
#define FRAMECOUNT_INC(x)   ( ((x) & DEBUGCHAN_FLAG) | (((x)+1) & ~DEBUGCHAN_FLAG) )
#define LOAD_OH(oh)
#define MAX_LANGUAGE   20
#define MAX_MUSICCLASS   80

Typedefs

typedef int(*) ast_acf_read_fn_t (struct ast_channel *, char *, char *, char *, size_t)
 Typedef for a custom read function.
typedef int(*) ast_acf_write_fn_t (struct ast_channel *, char *, char *, const char *)
 Typedef for a custom write function.
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_FLAG_BRIDGE_HANGUP_RUN = (1 << 16),
  AST_FLAG_BRIDGE_HANGUP_DONT = (1 << 17), AST_FLAG_IN_CHANNEL_LIST = (1 << 19), AST_FLAG_DISABLE_WORKAROUNDS = (1 << 20)
}
 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_FEATURE_NO_H_EXTEN = (1 << 6), AST_FEATURE_WARNING_ACTIVE = (1 << 7)
}
 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), AST_SOFTHANGUP_ALL = (0xFFFFFFFF)
}
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

ast_channel__ast_request_and_dial (const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname, struct outgoing_helper *oh)
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
int ast_answer (struct ast_channel *chan)
 Answer a ringing call.
int ast_autoservice_ignore (struct ast_channel *chan, enum ast_frame_type ftype)
 Ignore certain frame types.
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.
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.
ast_channelast_call_forward (struct ast_channel *caller, struct ast_channel *orig, int *timeout, int format, struct outgoing_helper *oh, int *outstate)
 Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated.
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.
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.
void ast_channel_clear_softhangup (struct ast_channel *chan, int flag)
 Clear a set of softhangup flags from a channel.
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.
ast_datastoreast_channel_datastore_alloc (const struct ast_datastore_info *info, char *uid)
 Create a channel datastore structure.
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.
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.
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.
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.
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.
ast_channelast_get_channel_by_exten_locked (const char *exten, const char *context)
 Get channel by exten (and optionally context) and lock it.
ast_channelast_get_channel_by_name_locked (const char *chan)
 Get channel by name (locks channel).
ast_channelast_get_channel_by_name_prefix_locked (const char *name, const int namelen)
 Get channel by name prefix (locks channel).
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.
int ast_is_deferrable_frame (const struct ast_frame *frame)
 Should we keep this frame for later?
int ast_plc_reload (void)
 Reload genericplc configuration value from codecs.conf.
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 one or more frames to a channel's frame queue.
int ast_queue_frame_head (struct ast_channel *chan, struct ast_frame *f)
 Queue one or more frames to the head of a channel's frame queue.
int ast_queue_hangup (struct ast_channel *chan)
 Queue a hangup frame.
ast_frameast_read (struct ast_channel *chan)
 Reads a frame.
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.
ast_channelast_request (const char *type, int format, void *data, int *status)
 Requests a channel.
ast_channelast_request_and_dial (const char *type, int format, void *data, int timeout, int *reason, const char *cidnum, const char *cidname)
 Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
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
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 *text)
 Sends text to a channel Write text to a display on a channel.
void ast_set_callerid (struct ast_channel *chan, const char *cidnum, const char *cidname, const char *ani)
int ast_set_read_format (struct ast_channel *chan, int format)
 Sets read format on channel chan Set read format for channel to whichever component of "format" is best.
void ast_set_variables (struct ast_channel *chan, struct ast_variable *vars)
 adds a list of channel variables to a channel
int ast_set_write_format (struct ast_channel *chan, int format)
 Sets write format on channel chan Set write format for channel to whichever compoent of "format" is best.
int ast_setstate (struct ast_channel *chan, enum ast_channel_state)
 Change the state of a 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.
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.
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.
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.
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.


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

Referenced by agent_read().

#define AST_ALERT_FD   (AST_MAX_FDS-1)

used for alertpipe

Definition at line 125 of file channel.h.

Referenced by restore_channel().

#define AST_BRIDGE_DTMF_CHANNEL_0   (1 << 0)

Report DTMF on channel 0.

Definition at line 1137 of file channel.h.

Referenced by ast_generic_bridge(), bridge_native_loop(), dahdi_bridge(), iax2_bridge(), misdn_bridge(), and set_config_flags().

#define AST_BRIDGE_DTMF_CHANNEL_1   (1 << 1)

Report DTMF on channel 1.

Definition at line 1139 of file channel.h.

Referenced by ast_generic_bridge(), bridge_native_loop(), dahdi_bridge(), iax2_bridge(), misdn_bridge(), and set_config_flags().

#define AST_BRIDGE_IGNORE_SIGS   (1 << 4)

Ignore all signal frames except NULL.

Definition at line 1145 of file channel.h.

Referenced by bridge_native_loop().

#define AST_BRIDGE_REC_CHANNEL_0   (1 << 2)

Return all voice frames on channel 0.

Definition at line 1141 of file channel.h.

#define AST_BRIDGE_REC_CHANNEL_1   (1 << 3)

Return all voice frames on channel 1.

Definition at line 1143 of file channel.h.

#define AST_CHAN_WRITE_INFO_T_VERSION   1

ast_chan_write_info_t version. Must be incremented if structure is changed

Definition at line 206 of file channel.h.

Referenced by func_channel_write(), and local_setoption().

#define AST_CHANNEL_NAME   80

Max length of an ast_channel name

Definition at line 102 of file channel.h.

Referenced by agent_devicestate_cb(), ast_channel_free(), ast_parse_device_state(), ast_setstate(), create_jb(), fast_originate(), next_channel(), page_exec(), park_call_full(), and softhangup_exec().

#define AST_GENERATOR_FD   (AST_MAX_FDS-4)

used by generator

Definition at line 128 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 101 of file channel.h.

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

#define AST_MAX_EXTENSION   80

Max length of an extension

Definition at line 100 of file channel.h.

Referenced by add_extensions(), advanced_options(), ast_bridge_call(), ast_device_state_changed(), ast_ivr_menu_run_internal(), begin_dial(), conf_run(), destroy_station(), disa_exec(), do_parking_thread(), dundi_lookup_local(), forward_message(), function_enum(), get_destination(), gosub_exec(), leave_voicemail(), load_config(), log_exec(), mgcp_ss(), park_add_hints(), park_call_exec(), phone_check_exception(), process_dahdi(), realtime_switch_common(), show_dialplan_helper(), skinny_answer(), skinny_indicate(), skinny_ss(), speech_background(), ss_thread(), transmit_state_notify(), try_calling(), vm_authenticate(), vmauthenticate(), and wait_for_answer().

#define AST_MAX_FDS   8

Definition at line 120 of file channel.h.

Referenced by ast_channel_alloc(), ast_do_masquerade(), ast_waitfor_nandfds(), and update_features().

#define AST_TIMING_FD   (AST_MAX_FDS-2)

used for timingfd

Definition at line 126 of file channel.h.

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

#define CHECK_BLOCKING (  ) 

Definition at line 1453 of file channel.h.

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

#define DATASTORE_INHERIT_FOREVER   INT_MAX

Definition at line 118 of file channel.h.

Referenced by _macro_exec(), add_features_datastores(), ast_channel_datastore_inherit(), and try_calling().

#define DEBUGCHAN_FLAG   0x80000000

Definition at line 312 of file channel.h.

Referenced by __ast_read(), ast_write(), handle_core_set_debug_channel(), handle_debugchan_deprecated(), handle_nodebugchan_deprecated(), handle_showchan(), handle_showchan_deprecated(), and serialize_showchan().

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

Definition at line 313 of file channel.h.

Referenced by __ast_read(), and ast_write().

#define LOAD_OH ( oh   ) 

Definition at line 581 of file channel.h.

Referenced by ast_pbx_outgoing_exten().

#define MAX_LANGUAGE   20

Max length of the language setting

Definition at line 103 of file channel.h.

#define MAX_MUSICCLASS   80

Max length of the music class setting

Definition at line 104 of file channel.h.


Typedef Documentation

typedef int(*) ast_acf_read_fn_t(struct ast_channel *, char *, char *, char *, size_t)

Typedef for a custom read function.

Definition at line 198 of file channel.h.

typedef int(*) ast_acf_write_fn_t(struct ast_channel *, char *, char *, const char *)

Typedef for a custom write function.

Definition at line 201 of file channel.h.

typedef unsigned long long ast_group_t

Definition at line 137 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 482 of file channel.h.

00482      {
00483    /*! \brief Channels have this property if they can accept input with jitter; 
00484     *         i.e. most VoIP channels */
00485    AST_CHAN_TP_WANTSJITTER = (1 << 0),
00486    /*! \brief Channels have this property if they can create jitter; 
00487     *         i.e. most VoIP channels */
00488    AST_CHAN_TP_CREATESJITTER = (1 << 1),
00489 };

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
AST_FLAG_BRIDGE_HANGUP_RUN  This flag indicates that the hangup exten was run when the bridge terminated, a message aimed at preventing a subsequent hangup exten being run at the pbx_run level
AST_FLAG_BRIDGE_HANGUP_DONT  This flag indicates that the hangup exten should NOT be run when the bridge terminates, this will allow the hangup in the pbx loop to be run instead.
AST_FLAG_IN_CHANNEL_LIST  This flag indicates whether the channel is in the channel list or not.
AST_FLAG_DISABLE_WORKAROUNDS  Disable certain workarounds. This reintroduces certain bugs, but allows some non-traditional dialplans (like AGI) to continue to function.

Definition at line 492 of file channel.h.

00492      {
00493    /*! Queue incoming dtmf, to be released when this flag is turned off */
00494    AST_FLAG_DEFER_DTMF =    (1 << 1),
00495    /*! write should be interrupt generator */
00496    AST_FLAG_WRITE_INT =     (1 << 2),
00497    /*! a thread is blocking on this channel */
00498    AST_FLAG_BLOCKING =      (1 << 3),
00499    /*! This is a zombie channel */
00500    AST_FLAG_ZOMBIE =        (1 << 4),
00501    /*! There is an exception pending */
00502    AST_FLAG_EXCEPTION =     (1 << 5),
00503    /*! Listening to moh XXX anthm promises me this will disappear XXX */
00504    AST_FLAG_MOH =           (1 << 6),
00505    /*! This channel is spying on another channel */
00506    AST_FLAG_SPYING =        (1 << 7),
00507    /*! This channel is in a native bridge */
00508    AST_FLAG_NBRIDGE =       (1 << 8),
00509    /*! the channel is in an auto-incrementing dialplan processor,
00510     *  so when ->priority is set, it will get incremented before
00511     *  finding the next priority to run */
00512    AST_FLAG_IN_AUTOLOOP =   (1 << 9),
00513    /*! This is an outgoing call */
00514    AST_FLAG_OUTGOING =      (1 << 10),
00515    /*! This channel is being whispered on */
00516    AST_FLAG_WHISPER =       (1 << 11),
00517    /*! A DTMF_BEGIN frame has been read from this channel, but not yet an END */
00518    AST_FLAG_IN_DTMF =       (1 << 12),
00519    /*! A DTMF_END was received when not IN_DTMF, so the length of the digit is 
00520     *  currently being emulated */
00521    AST_FLAG_EMULATE_DTMF =  (1 << 13),
00522    /*! This is set to tell the channel not to generate DTMF begin frames, and
00523     *  to instead only generate END frames. */
00524    AST_FLAG_END_DTMF_ONLY = (1 << 14),
00525    /*! This flag indicates that on a masquerade, an active stream should not
00526     *  be carried over */
00527    AST_FLAG_MASQ_NOSTREAM = (1 << 15),
00528    /*! This flag indicates that the hangup exten was run when the bridge terminated,
00529     *  a message aimed at preventing a subsequent hangup exten being run at the pbx_run
00530     *  level */
00531    AST_FLAG_BRIDGE_HANGUP_RUN = (1 << 16),
00532    /*! This flag indicates that the hangup exten should NOT be run when the 
00533     *  bridge terminates, this will allow the hangup in the pbx loop to be run instead.
00534     *  */
00535    AST_FLAG_BRIDGE_HANGUP_DONT = (1 << 17),
00536    /*! This flag indicates whether the channel is in the channel list or not. */
00537    AST_FLAG_IN_CHANNEL_LIST = (1 << 19),
00538    /*! Disable certain workarounds.  This reintroduces certain bugs, but allows
00539     *  some non-traditional dialplans (like AGI) to continue to function.
00540     */
00541    AST_FLAG_DISABLE_WORKAROUNDS = (1 << 20),
00542 };

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 
AST_FEATURE_NO_H_EXTEN 
AST_FEATURE_WARNING_ACTIVE 

Definition at line 545 of file channel.h.

00545      {
00546    AST_FEATURE_PLAY_WARNING = (1 << 0),
00547    AST_FEATURE_REDIRECT =     (1 << 1),
00548    AST_FEATURE_DISCONNECT =   (1 << 2),
00549    AST_FEATURE_ATXFER =       (1 << 3),
00550    AST_FEATURE_AUTOMON =      (1 << 4),
00551    AST_FEATURE_PARKCALL =     (1 << 5),
00552    AST_FEATURE_NO_H_EXTEN =   (1 << 6),
00553    AST_FEATURE_WARNING_ACTIVE = (1 << 7),
00554 };

anonymous enum

Enumerator:
AST_CDR_TRANSFER 
AST_CDR_FORWARD 
AST_CDR_CALLWAIT 
AST_CDR_CONFERENCE 

Definition at line 603 of file channel.h.

00603      {
00604    AST_CDR_TRANSFER =   (1 << 0),
00605    AST_CDR_FORWARD =    (1 << 1),
00606    AST_CDR_CALLWAIT =   (1 << 2),
00607    AST_CDR_CONFERENCE = (1 << 3),
00608 };

anonymous enum

Enumerator:
AST_SOFTHANGUP_DEV  Soft hangup requested by device or other internal reason. Actual hangup needed.
AST_SOFTHANGUP_ASYNCGOTO  Used to break the normal frame flow so an async goto can be done instead of actually hanging up.
AST_SOFTHANGUP_SHUTDOWN  Soft hangup requested by system shutdown. Actual hangup needed.
AST_SOFTHANGUP_TIMEOUT  Used to break the normal frame flow after a timeout so an implicit async goto can be done to the 'T' exten if it exists instead of actually hanging up. If the exten does not exist then actually hangup.
AST_SOFTHANGUP_APPUNLOAD  Soft hangup requested by application/channel-driver being unloaded. Actual hangup needed.
AST_SOFTHANGUP_EXPLICIT  Soft hangup requested by non-associated party. Actual hangup needed.
AST_SOFTHANGUP_UNBRIDGE  Used to break a bridge so the channel can be spied upon instead of actually hanging up.
AST_SOFTHANGUP_ALL  All softhangup flags.

This can be used as an argument to ast_channel_softhangup_clear to clear all softhangup flags from a channel.

Definition at line 610 of file channel.h.

00610      {
00611    /*!
00612     * Soft hangup requested by device or other internal reason.
00613     * Actual hangup needed.
00614     */
00615    AST_SOFTHANGUP_DEV =       (1 << 0),
00616    /*!
00617     * Used to break the normal frame flow so an async goto can be
00618     * done instead of actually hanging up.
00619     */
00620    AST_SOFTHANGUP_ASYNCGOTO = (1 << 1),
00621    /*!
00622     * Soft hangup requested by system shutdown.  Actual hangup
00623     * needed.
00624     */
00625    AST_SOFTHANGUP_SHUTDOWN =  (1 << 2),
00626    /*!
00627     * Used to break the normal frame flow after a timeout so an
00628     * implicit async goto can be done to the 'T' exten if it exists
00629     * instead of actually hanging up.  If the exten does not exist
00630     * then actually hangup.
00631     */
00632    AST_SOFTHANGUP_TIMEOUT =   (1 << 3),
00633    /*!
00634     * Soft hangup requested by application/channel-driver being
00635     * unloaded.  Actual hangup needed.
00636     */
00637    AST_SOFTHANGUP_APPUNLOAD = (1 << 4),
00638    /*!
00639     * Soft hangup requested by non-associated party.  Actual hangup
00640     * needed.
00641     */
00642    AST_SOFTHANGUP_EXPLICIT =  (1 << 5),
00643    /*!
00644     * Used to break a bridge so the channel can be spied upon
00645     * instead of actually hanging up.
00646     */
00647    AST_SOFTHANGUP_UNBRIDGE =  (1 << 6),
00648 
00649 
00650    /*!
00651     * \brief All softhangup flags.
00652     *
00653     * This can be used as an argument to ast_channel_softhangup_clear
00654     * to clear all softhangup flags from a channel.
00655     */
00656    AST_SOFTHANGUP_ALL =       (0xFFFFFFFF)
00657 };

enum ast_bridge_result

Enumerator:
AST_BRIDGE_COMPLETE 
AST_BRIDGE_FAILED 
AST_BRIDGE_FAILED_NOWARN 
AST_BRIDGE_RETRY 

Definition at line 130 of file channel.h.

00130                        {
00131    AST_BRIDGE_COMPLETE = 0,
00132    AST_BRIDGE_FAILED = -1,
00133    AST_BRIDGE_FAILED_NOWARN = -2,
00134    AST_BRIDGE_RETRY = -3,
00135 };

enum ast_channel_adsicpe

Enumerator:
AST_ADSI_UNKNOWN 
AST_ADSI_AVAILABLE 
AST_ADSI_UNAVAILABLE 
AST_ADSI_OFFHOOKONLY 

Definition at line 315 of file channel.h.

enum ast_channel_state

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

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

enum channelreloadreason

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


Function Documentation

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

Definition at line 3587 of file channel.c.

References ast_channel::_state, outgoing_helper::account, ast_call(), ast_call_forward(), AST_CAUSE_NO_ANSWER, ast_cdr_alloc(), ast_cdr_answer(), ast_cdr_busy(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), AST_CDR_FLAG_ORIGINATED, ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_inherit_variables(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_copy_string(), AST_FRAME_CONTROL, ast_frfree, ast_hangup(), ast_log(), ast_read(), ast_request(), ast_set_callerid(), ast_set_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), ast_channel::call_forward, ast_channel::cdr, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, f, handle_cause(), ast_channel::hangupcause, LOG_NOTICE, outgoing_helper::parent_channel, ast_channel::priority, outgoing_helper::priority, and outgoing_helper::vars.

Referenced by ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_request_and_dial(), and parkandannounce_exec().

03588 {
03589    int dummy_outstate;
03590    int cause = 0;
03591    struct ast_channel *chan;
03592    int res = 0;
03593    int last_subclass = 0;
03594    
03595    if (outstate)
03596       *outstate = 0;
03597    else
03598       outstate = &dummy_outstate;   /* make outstate always a valid pointer */
03599 
03600    chan = ast_request(type, format, data, &cause);
03601    if (!chan) {
03602       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
03603       handle_cause(cause, outstate);
03604       return NULL;
03605    }
03606 
03607    if (oh) {
03608       if (oh->vars)  
03609          ast_set_variables(chan, oh->vars);
03610       /* XXX why is this necessary, for the parent_channel perhaps ? */
03611       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
03612          ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
03613       if (oh->parent_channel)
03614          ast_channel_inherit_variables(oh->parent_channel, chan);
03615       if (oh->account)
03616          ast_cdr_setaccount(chan, oh->account); 
03617    }
03618    ast_set_callerid(chan, cid_num, cid_name, cid_num);
03619    ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
03620 
03621    if (ast_call(chan, data, 0)) {   /* ast_call failed... */
03622       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
03623    } else {
03624       res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
03625       while (timeout && chan->_state != AST_STATE_UP) {
03626          struct ast_frame *f;
03627          res = ast_waitfor(chan, timeout);
03628          if (res == 0) { /* timeout, treat it like ringing */
03629             *outstate = AST_CONTROL_RINGING;
03630             break;
03631          }
03632          if (res < 0) /* error or done */
03633             break;
03634          if (timeout > -1)
03635             timeout = res;
03636          if (!ast_strlen_zero(chan->call_forward)) {
03637             if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) {
03638                return NULL;
03639             }
03640             continue;
03641          }
03642 
03643          f = ast_read(chan);
03644          if (!f) {
03645             *outstate = AST_CONTROL_HANGUP;
03646             res = 0;
03647             break;
03648          }
03649          if (f->frametype == AST_FRAME_CONTROL) {
03650             switch (f->subclass) {
03651             case AST_CONTROL_RINGING:  /* record but keep going */
03652                *outstate = f->subclass;
03653                break;
03654 
03655             case AST_CONTROL_BUSY:
03656                ast_cdr_busy(chan->cdr);
03657                *outstate = f->subclass;
03658                timeout = 0;
03659                break;
03660 
03661             case AST_CONTROL_CONGESTION:
03662                ast_cdr_failed(chan->cdr);
03663                *outstate = f->subclass;
03664                timeout = 0;
03665                break;
03666 
03667             case AST_CONTROL_ANSWER:
03668                ast_cdr_answer(chan->cdr);
03669                *outstate = f->subclass;
03670                timeout = 0;      /* trick to force exit from the while() */
03671                break;
03672 
03673             /* Ignore these */
03674             case AST_CONTROL_PROGRESS:
03675             case AST_CONTROL_PROCEEDING:
03676             case AST_CONTROL_HOLD:
03677             case AST_CONTROL_UNHOLD:
03678             case AST_CONTROL_VIDUPDATE:
03679             case AST_CONTROL_SRCUPDATE:
03680             case AST_CONTROL_SRCCHANGE:
03681             case -1:       /* Ignore -- just stopping indications */
03682                break;
03683 
03684             default:
03685                ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
03686             }
03687             last_subclass = f->subclass;
03688          }
03689          ast_frfree(f);
03690       }
03691    }
03692 
03693    /* Final fixups */
03694    if (oh) {
03695       if (!ast_strlen_zero(oh->context))
03696          ast_copy_string(chan->context, oh->context, sizeof(chan->context));
03697       if (!ast_strlen_zero(oh->exten))
03698          ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
03699       if (oh->priority) 
03700          chan->priority = oh->priority;
03701    }
03702    if (chan->_state == AST_STATE_UP)
03703       *outstate = AST_CONTROL_ANSWER;
03704 
03705    if (res <= 0) {
03706       if ( AST_CONTROL_RINGING == last_subclass ) 
03707          chan->hangupcause = AST_CAUSE_NO_ANSWER;
03708       if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
03709          ast_cdr_init(chan->cdr, chan);
03710       if (chan->cdr) {
03711          char tmp[256];
03712          snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
03713          ast_cdr_setapp(chan->cdr,"Dial",tmp);
03714          ast_cdr_update(chan);
03715          ast_cdr_start(chan->cdr);
03716          ast_cdr_end(chan->cdr);
03717          /* If the cause wasn't handled properly */
03718          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
03719             ast_cdr_failed(chan->cdr);
03720       }
03721       ast_hangup(chan);
03722       chan = NULL;
03723    }
03724    return chan;
03725 }

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

Activate a given generator

Definition at line 1820 of file channel.c.

References ast_generator::alloc, ast_channel_lock, ast_channel_unlock, ast_prod(), ast_settimeout(), gen, 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(), and old_milliwatt_exec().

01821 {
01822    int res = 0;
01823 
01824    ast_channel_lock(chan);
01825    if (chan->generatordata) {
01826       if (chan->generator && chan->generator->release)
01827          chan->generator->release(chan, chan->generatordata);
01828       chan->generatordata = NULL;
01829    }
01830    if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
01831       res = -1;
01832    }
01833    if (!res) {
01834       ast_settimeout(chan, 160, generator_force, chan);
01835       chan->generator = gen;
01836    }
01837    ast_channel_unlock(chan);
01838 
01839    ast_prod(chan);
01840 
01841    return res;
01842 }

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns number of active/allocated channels

Definition at line 443 of file channel.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.

Referenced by action_corestatus(), dahdi_restart(), handle_show_settings(), and quit_handler().

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

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

Referenced by ast_waitfor_nandfds().

01428 {
01429    pfd->fd = fd;
01430    pfd->events = POLLIN | POLLPRI;
01431    return fd >= 0;
01432 }

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 1741 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_indicate(), 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(), answer_trunk_chan(), app_exec(), ast_bridge_call(), ast_control_streamfile(), auth_exec(), background_detect_exec(), builtin_parkcall(), common_exec(), conf_exec(), count_exec(), dictate_exec(), directory_exec(), disa_exec(), exec(), features_answer(), handle_answer(), ices_exec(), old_milliwatt_exec(), park_call_exec(), park_exec(), pbx_builtin_answer(), pbx_builtin_background(), pickup_do(), playback_exec(), privacy_exec(), read_exec(), sayunixtime_exec(), send_waveform_to_channel(), skel_exec(), sla_station_exec(), speech_background(), testclient_exec(), testserver_exec(), vm_exec(), vm_execmain(), waitforsilence_exec(), and zapateller_exec().

01742 {
01743    int res = 0;
01744    ast_channel_lock(chan);
01745    /* You can't answer an outbound call */
01746    if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
01747       ast_channel_unlock(chan);
01748       return 0;
01749    }
01750    /* Stop if we're a zombie or need a soft hangup */
01751    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01752       ast_channel_unlock(chan);
01753       return -1;
01754    }
01755    switch(chan->_state) {
01756    case AST_STATE_RINGING:
01757    case AST_STATE_RING:
01758       if (chan->tech->answer)
01759          res = chan->tech->answer(chan);
01760       ast_setstate(chan, AST_STATE_UP);
01761       ast_cdr_answer(chan->cdr);
01762       break;
01763    case AST_STATE_UP:
01764       break;
01765    default:
01766       break;
01767    }
01768    ast_indicate(chan, -1);
01769    chan->visible_indication = 0;
01770    ast_channel_unlock(chan);
01771    return res;
01772 }

int ast_autoservice_ignore ( struct ast_channel chan,
enum ast_frame_type  ftype 
)

Ignore certain frame types.

Note:
Normally, we cache DTMF, IMAGE, HTML, TEXT, and CONTROL frames while a channel is in autoservice and queue them up when taken out of autoservice. When this is not desireable, this API may be used to cause the channel to ignore those frametypes after the channel is put into autoservice, but before autoservice is stopped.
Return values:
0 success
-1 channel is not in autoservice

Definition at line 308 of file autoservice.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, asent::chan, asent::ignore_frame_types, and asent::list.

Referenced by builtin_automonitor(), builtin_blindtransfer(), and feature_exec_app().

00309 {
00310    struct asent *as;
00311    int res = -1;
00312 
00313    AST_LIST_LOCK(&aslist);
00314    AST_LIST_TRAVERSE(&aslist, as, list) {
00315       if (as->chan == chan) {
00316          res = 0;
00317          as->ignore_frame_types |= (1 << ftype);
00318          break;
00319       }
00320    }
00321    AST_LIST_UNLOCK(&aslist);
00322    return res;
00323 }

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

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

Referenced by _macro_exec(), acf_curl_exec(), acf_odbc_read(), acf_odbc_write(), 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_realtime_read(), function_realtime_write(), osplookup_exec(), sla_station_exec(), smdi_msg_retrieve_read(), and system_exec_helper().

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

int ast_autoservice_stop ( struct ast_channel chan  ) 

Stop servicing a channel for us...

Note:
if chan is locked prior to calling ast_autoservice_stop, it is likely that there will be a deadlock between the thread that calls ast_autoservice_stop and the autoservice thread. It is important that chan is not locked prior to this call
Return values:
0 success
-1 error, or the channel has been hungup

Definition at line 239 of file autoservice.c.

References ast_channel::_softhangup, as_chan_list_state, ast_channel_lock, ast_channel_unlock, ast_clear_flag, AST_FLAG_END_DTMF_ONLY, ast_frfree, AST_LIST_LOCK, AST_LIST_REMOVE_CURRENT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_LIST_UNLOCK, AST_PTHREADT_NULL, ast_queue_frame_head(), asthread, asent::chan, asent::deferred_frames, f, free, asent::ignore_frame_types, asent::list, asent::orig_end_dtmf_flag, and asent::use_count.

Referenced by _macro_exec(), acf_curl_exec(), acf_odbc_read(), acf_odbc_write(), ast_dtmf_stream(), ast_get_srv(), ast_get_txt(), ast_hangup(), bridge_playfile(), builtin_atxfer(), builtin_automonitor(), conf_play(), feature_exec_app(), finishup(), function_realtime_read(), function_realtime_write(), osplookup_exec(), sla_station_exec(), smdi_msg_retrieve_read(), and system_exec_helper().

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

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

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

Referenced by quit_handler().

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

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

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

struct ast_channel* ast_bridged_channel ( struct ast_channel chan  ) 

Find bridged channel.

Parameters:
chan Current channel

Definition at line 4511 of file channel.c.

References ast_channel::_bridge, ast_channel_tech::bridged_channel, and ast_channel::tech.

Referenced by __ast_read(), __dahdi_exception(), action_agents(), agents_show(), agents_show_online(), ast_bridge_call(), ast_channel_masquerade(), ast_do_masquerade(), attempt_transfer(), cb_events(), check_bridge(), common_exec(), console_transfer(), console_transfer_deprecated(), create_jb(), dahdi_handle_event(), dahdi_hangup(), export_aoc_vars(), handle_chanlist(), handle_chanlist_deprecated(), handle_hd_hf(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response_invite(), handle_showchan(), handle_showchan_deprecated(), local_attended_transfer(), mgcp_hangup(), mgcp_ss(), misdn_attempt_transfer(), mixmonitor_thread(), park_call_full(), schedule_delivery(), sip_read(), sip_set_rtp_peer(), socket_process(), ss_thread(), start_spying(), and startmon().

04512 {
04513    struct ast_channel *bridged;
04514    bridged = chan->_bridge;
04515    if (bridged && bridged->tech->bridged_channel)
04516       bridged = bridged->tech->bridged_channel(chan, bridged);
04517    return bridged;
04518 }

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

References AST_CDR_FLAG_DIALED, 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, ast_channel::cdr, and ast_channel::tech.

Referenced by __ast_request_and_dial(), agent_call(), ast_call_forward(), attempt_reconnect(), begin_dial(), connect_link(), do_idle_thread(), feature_request_and_dial(), features_call(), findmeexec(), ring_entry(), rpt(), and wait_for_answer().

03783 {
03784    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
03785       If the remote end does not answer within the timeout, then do NOT hang up, but
03786       return anyway.  */
03787    int res = -1;
03788    /* Stop if we're a zombie or need a soft hangup */
03789    ast_channel_lock(chan);
03790    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03791       if (chan->cdr) {
03792          ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED);
03793       }
03794       if (chan->tech->call)
03795          res = chan->tech->call(chan, addr, timeout);
03796       ast_set_flag(chan, AST_FLAG_OUTGOING);
03797    }
03798    ast_channel_unlock(chan);
03799    return res;
03800 }

struct ast_channel* ast_call_forward ( struct ast_channel caller,
struct ast_channel orig,
int *  timeout,
int  format,
struct outgoing_helper oh,
int *  outstate 
)

Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated.

Parameters:
caller in channel that requested orig
orig channel being replaced by the call forward channel
timeout maximum amount of time to wait for setup of new forward channel
format requested channel format
oh outgoing helper used with original channel
outstate reason why unsuccessful (if uncuccessful)
Returns:
Returns the forwarded call's ast_channel on success or NULL on failure

Definition at line 3515 of file channel.c.

References outgoing_helper::account, ast_channel::accountcode, accountcode, ast_call(), ast_cdr_setaccount(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_unlock, ast_copy_string(), ast_hangup(), ast_log(), ast_request(), ast_set_callerid(), ast_set_variables(), ast_string_field_set, ast_strlen_zero(), ast_channel::call_forward, ast_channel::cid, ast_callerid::cid_name, outgoing_helper::cid_name, ast_callerid::cid_num, outgoing_helper::cid_num, ast_channel::context, ast_channel::data, handle_cause(), LOG_NOTICE, outgoing_helper::parent_channel, pbx_builtin_getvar_helper(), S_OR, type, and outgoing_helper::vars.

Referenced by __ast_request_and_dial(), and feature_request_and_dial().

03516 {
03517    char tmpchan[256];
03518    struct ast_channel *new = NULL;
03519    char *data, *type;
03520    int cause = 0;
03521    int res;
03522 
03523    /* gather data and request the new forward channel */
03524    ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan));
03525    if ((data = strchr(tmpchan, '/'))) {
03526       *data++ = '\0';
03527       type = tmpchan;
03528    } else {
03529       const char *forward_context;
03530       ast_channel_lock(orig);
03531       forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT");
03532       snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context));
03533       ast_channel_unlock(orig);
03534       data = tmpchan;
03535       type = "Local";
03536    }
03537    if (!(new = ast_request(type, format, data, &cause))) {
03538       ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
03539       handle_cause(cause, outstate);
03540       ast_hangup(orig);
03541       return NULL;
03542    }
03543 
03544    /* Copy/inherit important information into new channel */
03545    if (oh) {
03546       if (oh->vars) {
03547          ast_set_variables(new, oh->vars);
03548       }
03549       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
03550          ast_set_callerid(new, oh->cid_num, oh->cid_name, oh->cid_num);
03551       }
03552       if (oh->parent_channel) {
03553          ast_channel_inherit_variables(oh->parent_channel, new);
03554          ast_channel_datastore_inherit(oh->parent_channel, new);
03555       }
03556       if (oh->account) {
03557          ast_cdr_setaccount(new, oh->account);
03558       }
03559    } else if (caller) { /* no outgoing helper so use caller if avaliable */
03560       ast_channel_inherit_variables(caller, new);
03561       ast_channel_datastore_inherit(caller, new);
03562    }
03563 
03564    ast_channel_lock(orig);
03565    ast_string_field_set(new, accountcode, orig->accountcode);
03566    if (!ast_strlen_zero(orig->cid.cid_num) && !ast_strlen_zero(new->cid.cid_name)) {
03567       ast_set_callerid(new, orig->cid.cid_num, orig->cid.cid_name, orig->cid.cid_num);
03568    }
03569    ast_channel_unlock(orig);
03570 
03571    /* call new channel */
03572    res = ast_call(new, data, 0);
03573    if (timeout) {
03574       *timeout = res;
03575    }
03576    if (res) {
03577       ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data);
03578       ast_hangup(orig);
03579       ast_hangup(new);
03580       return NULL;
03581    }
03582    ast_hangup(orig);
03583 
03584    return new;
03585 }

void ast_cancel_shutdown ( void   ) 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 455 of file channel.c.

Referenced by handle_abort_halt().

00456 {
00457    shutting_down = 0;
00458 }

const char* ast_cause2str ( int  state  ) 

Gives the string form of a given hangup cause.

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

References causes, and desc.

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

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

void ast_change_name ( struct ast_channel chan,
char *  newname 
)

Change channel name.

Definition at line 4057 of file channel.c.

References ast_string_field_set, manager_event(), name, ast_channel::name, and ast_channel::uniqueid.

04058 {
04059    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
04060    ast_string_field_set(chan, name, newname);
04061 }

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

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

References ast_calloc, ast_log(), AST_MAX_FDS, ast_string_field_init, DAHDI_FILE_TIMER, ast_channel::flags, free, HAVE_DAHDI, LOG_WARNING, sched_context_create(), sched_context_destroy(), and chanlist::tech.

Referenced by __oh323_new(), acf_odbc_read(), acf_odbc_write(), action_getvar(), agent_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), builtin_atxfer(), check_goto_on_transfer(), dahdi_new(), features_new(), gtalk_new(), iax_park(), local_new(), make_email_file(), masq_park_call(), mgcp_new(), misdn_new(), nbs_new(), oss_new(), pbx_substitute_variables_helper_full(), phone_new(), sendpage(), sip_new(), sip_park(), and skinny_new().

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

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 4756 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_clear_softhangup(), ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_CONTROL_SRCUPDATE, AST_FEATURE_PLAY_WARNING, AST_FEATURE_REDIRECT, AST_FEATURE_WARNING_ACTIVE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_generic_bridge(), ast_indicate(), ast_log(), ast_samp2tv(), ast_set_flag, AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), ast_verbose(), ast_channel::audiohooks, ast_channel_tech::bridge, bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, config, ast_channel::generator, LOG_DEBUG, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::name, ast_channel::nativeformats, option_debug, option_verbose, ast_channel::readformat, ast_channel_tech::send_digit_begin, t, ast_channel::tech, ast_channel::uniqueid, update_bridgepeer(), VERBOSE_PREFIX_3, and ast_channel::writeformat.

Referenced by ast_bridge_call().

04758 {
04759    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
04760    int nativefailed=0;
04761    int firstpass;
04762    int o0nativeformats;
04763    int o1nativeformats;
04764    long time_left_ms=0;
04765    char caller_warning = 0;
04766    char callee_warning = 0;
04767 
04768    if (c0->_bridge) {
04769       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
04770          c0->name, c0->_bridge->name);
04771       return -1;
04772    }
04773    if (c1->_bridge) {
04774       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
04775          c1->name, c1->_bridge->name);
04776       return -1;
04777    }
04778    
04779    /* Stop if we're a zombie or need a soft hangup */
04780    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
04781        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
04782       return -1;
04783 
04784    *fo = NULL;
04785    firstpass = config->firstpass;
04786    config->firstpass = 0;
04787 
04788    if (ast_tvzero(config->start_time))
04789       config->start_time = ast_tvnow();
04790    time_left_ms = config->timelimit;
04791 
04792    caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
04793    callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
04794 
04795    if (config->start_sound && firstpass) {
04796       if (caller_warning)
04797          bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000);
04798       if (callee_warning)
04799          bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000);
04800    }
04801 
04802    /* Keep track of bridge */
04803    c0->_bridge = c1;
04804    c1->_bridge = c0;
04805 
04806    /* \todo  XXX here should check that cid_num is not NULL */
04807    manager_event(EVENT_FLAG_CALL, "Link",
04808             "Channel1: %s\r\n"
04809             "Channel2: %s\r\n"
04810             "Uniqueid1: %s\r\n"
04811             "Uniqueid2: %s\r\n"
04812             "CallerID1: %s\r\n"
04813             "CallerID2: %s\r\n",
04814             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04815 
04816    o0nativeformats = c0->nativeformats;
04817    o1nativeformats = c1->nativeformats;
04818 
04819    if (config->feature_timer && !ast_tvzero(config->nexteventts)) {
04820       config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
04821    } else if (config->timelimit && firstpass) {
04822       config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
04823       if (caller_warning || callee_warning)
04824          config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(config->play_warning, 1000));
04825    }
04826 
04827    if (!c0->tech->send_digit_begin)
04828       ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
04829    if (!c1->tech->send_digit_begin)
04830       ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
04831 
04832    /* Before we enter in and bridge these two together tell them both the source of audio has changed */
04833    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
04834    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
04835 
04836    for (/* ever */;;) {
04837       struct timeval now = { 0, };
04838       int to;
04839 
04840       to = -1;
04841 
04842       if (!ast_tvzero(config->nexteventts)) {
04843          now = ast_tvnow();
04844          to = ast_tvdiff_ms(config->nexteventts, now);
04845          if (to <= 0) {
04846             if (!config->timelimit) {
04847                res = AST_BRIDGE_COMPLETE;
04848                break;
04849             }
04850             to = 0;
04851          }
04852       }
04853 
04854       if (config->timelimit) {
04855          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
04856          if (time_left_ms < to)
04857             to = time_left_ms;
04858 
04859          if (time_left_ms <= 0) {
04860             if (caller_warning && config->end_sound)
04861                bridge_playfile(c0, c1, config->end_sound, 0);
04862             if (callee_warning && config->end_sound)
04863                bridge_playfile(c1, c0, config->end_sound, 0);
04864             *fo = NULL;
04865             res = 0;
04866             break;
04867          }
04868 
04869          if (!to) {
04870             if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
04871                int t = (time_left_ms + 500) / 1000; /* round to nearest second */
04872                if (caller_warning)
04873                   bridge_playfile(c0, c1, config->warning_sound, t);
04874                if (callee_warning)
04875                   bridge_playfile(c1, c0, config->warning_sound, t);
04876             }
04877             if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000)))
04878                config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
04879             else
04880                config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
04881          }
04882          ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
04883       }
04884 
04885       if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */
04886          if (c0->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
04887             ast_channel_clear_softhangup(c0, AST_SOFTHANGUP_UNBRIDGE);
04888          }
04889          if (c1->_softhangup & AST_SOFTHANGUP_UNBRIDGE) {
04890             ast_channel_clear_softhangup(c1, AST_SOFTHANGUP_UNBRIDGE);
04891          }
04892          c0->_bridge = c1;
04893          c1->_bridge = c0;
04894          if (option_debug)
04895             ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
04896          continue;
04897       }
04898 
04899       /* Stop if we're a zombie or need a soft hangup */
04900       if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
04901           ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
04902          *fo = NULL;
04903          res = 0;
04904          if (option_debug)
04905             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",
04906                c0->name, c1->name,
04907                ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
04908                ast_check_hangup(c0) ? "Yes" : "No",
04909                ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
04910                ast_check_hangup(c1) ? "Yes" : "No");
04911          break;
04912       }
04913 
04914       update_bridgepeer(c0, c1);
04915 
04916       if (c0->tech->bridge &&
04917           (config->timelimit == 0) &&
04918           (c0->tech->bridge == c1->tech->bridge) &&
04919           !nativefailed && !c0->monitor && !c1->monitor &&
04920           !c0->audiohooks && !c1->audiohooks && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) &&
04921           !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) &&
04922           !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
04923          /* Looks like they share a bridge method and nothing else is in the way */
04924          ast_set_flag(c0, AST_FLAG_NBRIDGE);
04925          ast_set_flag(c1, AST_FLAG_NBRIDGE);
04926          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
04927             /* \todo  XXX here should check that cid_num is not NULL */
04928             manager_event(EVENT_FLAG_CALL, "Unlink",
04929                      "Channel1: %s\r\n"
04930                      "Channel2: %s\r\n"
04931                      "Uniqueid1: %s\r\n"
04932                      "Uniqueid2: %s\r\n"
04933                      "CallerID1: %s\r\n"
04934                      "CallerID2: %s\r\n",
04935                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04936             if (option_debug)
04937                ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
04938 
04939             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
04940             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
04941 
04942             if ((c0->_softhangup | c1->_softhangup) & AST_SOFTHANGUP_UNBRIDGE) {/* Bit operators are intentional. */
04943                continue;
04944             }
04945 
04946             c0->_bridge = NULL;
04947             c1->_bridge = NULL;
04948 
04949             return res;
04950          } else {
04951             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
04952             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
04953          }
04954          switch (res) {
04955          case AST_BRIDGE_RETRY:
04956             if (config->play_warning) {
04957                ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
04958             }
04959             continue;
04960          default:
04961             if (option_verbose > 2)
04962                ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s ended\n",
04963                       c0->name, c1->name);
04964             /* fallthrough */
04965          case AST_BRIDGE_FAILED_NOWARN:
04966             nativefailed++;
04967             break;
04968          }
04969       }
04970 
04971       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
04972           (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
04973           !(c0->generator || c1->generator)) {
04974          if (ast_channel_make_compatible(c0, c1)) {
04975             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
04976             /* \todo  XXX here should check that cid_num is not NULL */
04977                                 manager_event(EVENT_FLAG_CALL, "Unlink",
04978                      "Channel1: %s\r\n"
04979                      "Channel2: %s\r\n"
04980                      "Uniqueid1: %s\r\n"
04981                      "Uniqueid2: %s\r\n"
04982                      "CallerID1: %s\r\n"
04983                      "CallerID2: %s\r\n",
04984                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04985             return AST_BRIDGE_FAILED;
04986          }
04987          o0nativeformats = c0->nativeformats;
04988          o1nativeformats = c1->nativeformats;
04989       }
04990 
04991       update_bridgepeer(c0, c1);
04992 
04993       res = ast_generic_bridge(c0, c1, config, fo, rc, config->nexteventts);
04994       if (res != AST_BRIDGE_RETRY) {
04995          break;
04996       } else if (config->feature_timer) {
04997          /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */
04998          break;
04999       }
05000    }
05001 
05002    ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
05003    ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
05004 
05005    /* Now that we have broken the bridge the source will change yet again */
05006    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
05007    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
05008 
05009    c0->_bridge = NULL;
05010    c1->_bridge = NULL;
05011 
05012    /* \todo  XXX here should check that cid_num is not NULL */
05013    manager_event(EVENT_FLAG_CALL, "Unlink",
05014             "Channel1: %s\r\n"
05015             "Channel2: %s\r\n"
05016             "Uniqueid1: %s\r\n"
05017             "Uniqueid2: %s\r\n"
05018             "CallerID1: %s\r\n"
05019             "CallerID2: %s\r\n",
05020             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
05021    if (option_debug)
05022       ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
05023 
05024    return res;
05025 }

void ast_channel_clear_softhangup ( struct ast_channel chan,
int  flag 
)

Clear a set of softhangup flags from a channel.

Never clear a softhangup flag from a channel directly. Instead, use this function. This ensures that all aspects of the softhangup process are aborted.

Parameters:
chan the channel to clear the flag on
flag the flag or flags to clear
Returns:
Nothing.

Definition at line 1573 of file channel.c.

References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, AST_CONTROL_END_OF_Q, AST_FRAME_CONTROL, ast_frfree, AST_LIST_LAST, AST_LIST_REMOVE, ast_frame::frametype, ast_channel::readq, and ast_frame::subclass.

Referenced by __ast_pbx_run(), ast_channel_bridge(), check_goto_on_transfer(), and collect_digits().

01574 {
01575    ast_channel_lock(chan);
01576 
01577    chan->_softhangup &= ~flag;
01578 
01579    if (!chan->_softhangup) {
01580       struct ast_frame *fr;
01581 
01582       /* If we have completely cleared the softhangup flag,
01583        * then we need to fully abort the hangup process.  This requires
01584        * pulling the END_OF_Q frame out of the channel frame queue if it
01585        * still happens to be there. */
01586 
01587       fr = AST_LIST_LAST(&chan->readq);
01588       if (fr && fr->frametype == AST_FRAME_CONTROL &&
01589             fr->subclass == AST_CONTROL_END_OF_Q) {
01590          AST_LIST_REMOVE(&chan->readq, fr, frame_list);
01591          ast_frfree(fr);
01592       }
01593    }
01594 
01595    ast_channel_unlock(chan);
01596 }

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

References ast_channel::whentohangup.

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

int ast_channel_datastore_add ( struct ast_channel chan,
struct ast_datastore datastore 
)

Add a datastore to a channel.

Definition at line 1521 of file channel.c.

References AST_LIST_INSERT_HEAD, ast_channel::datastores, and ast_datastore::entry.

Referenced by _macro_exec(), add_features_datastores(), apply_plc(), setup_chanspy_ds(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), smdi_msg_retrieve_read(), speech_create(), and try_calling().

01522 {
01523    int res = 0;
01524 
01525    AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
01526 
01527    return res;
01528 }

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

Create a channel datastore structure.

Definition at line 1457 of file channel.c.

References ast_calloc, ast_free, ast_strdup, ast_strlen_zero(), and ast_datastore::info.

Referenced by _macro_exec(), add_features_datastores(), apply_plc(), ast_channel_datastore_inherit(), setup_chanspy_ds(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), smdi_msg_retrieve_read(), speech_create(), and try_calling().

01458 {
01459    struct ast_datastore *datastore = NULL;
01460 
01461    /* Make sure we at least have type so we can identify this */
01462    if (info == NULL) {
01463       return NULL;
01464    }
01465 
01466    /* Allocate memory for datastore and clear it */
01467    datastore = ast_calloc(1, sizeof(*datastore));
01468    if (datastore == NULL) {
01469       return NULL;
01470    }
01471 
01472    datastore->info = info;
01473 
01474    if (!ast_strlen_zero(uid) && !(datastore->uid = ast_strdup(uid))) {
01475       ast_free(datastore);
01476       datastore = NULL;
01477    }
01478 
01479    return datastore;
01480 }

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

Find a datastore on a channel.

Definition at line 1548 of file channel.c.

References AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_channel::datastores, ast_datastore::entry, ast_datastore::info, and ast_datastore::uid.

Referenced by _macro_exec(), add_features_datastores(), apply_plc(), attended_transfer_occurred(), builtin_atxfer(), chanspy_ds_free(), clear_dialed_interfaces(), do_parking_thread(), find_speech(), func_inheritance_write(), park_exec(), queue_transfer_fixup(), smdi_msg_read(), speech_background(), speech_destroy(), stop_mixmonitor_exec(), and try_calling().

01549 {
01550    struct ast_datastore *datastore = NULL;
01551    
01552    if (info == NULL)
01553       return NULL;
01554 
01555    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
01556       if (datastore->info == info) {
01557          if (uid != NULL && datastore->uid != NULL) {
01558             if (!strcasecmp(uid, datastore->uid)) {
01559                /* Matched by type AND uid */
01560                break;
01561             }
01562          } else {
01563             /* Matched by type at least */
01564             break;
01565          }
01566       }
01567    }
01568    AST_LIST_TRAVERSE_SAFE_END
01569 
01570    return datastore;
01571 }

int ast_channel_datastore_free ( struct ast_datastore datastore  ) 

Free a channel datastore structure.

Definition at line 1482 of file channel.c.

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

Referenced by add_features_datastores(), adjust_frame_for_plc(), apply_plc(), ast_channel_free(), chanspy_ds_free(), clear_dialed_interfaces(), setup_inheritance_datastore(), stop_mixmonitor_exec(), and try_calling().

01483 {
01484    int res = 0;
01485 
01486    /* Using the destroy function (if present) destroy the data */
01487    if (datastore->info->destroy != NULL && datastore->data != NULL) {
01488       datastore->info->destroy(datastore->data);
01489       datastore->data = NULL;
01490    }
01491 
01492    /* Free allocated UID memory */
01493    if (datastore->uid != NULL) {
01494       free(datastore->uid);
01495       datastore->uid = NULL;
01496    }
01497 
01498    /* Finally free memory used by ourselves */
01499    free(datastore);
01500 
01501    return res;
01502 }

int ast_channel_datastore_inherit ( struct ast_channel from,
struct ast_channel to 
)

Inherit datastores from a parent to a child.

Definition at line 1504 of file channel.c.

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

Referenced by ast_call_forward(), findmeexec(), local_call(), ring_entry(), and wait_for_answer().

01505 {
01506    struct ast_datastore *datastore = NULL, *datastore2;
01507 
01508    AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
01509       if (datastore->inheritance > 0) {
01510          datastore2 = ast_channel_datastore_alloc(datastore->info, datastore->uid);
01511          if (datastore2) {
01512             datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL;
01513             datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
01514             AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
01515          }
01516       }
01517    }
01518    return 0;
01519 }

int ast_channel_datastore_remove ( struct ast_channel chan,
struct ast_datastore datastore 
)

Remove a datastore from a channel.

Definition at line 1530 of file channel.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_channel::datastores, and ast_datastore::entry.

Referenced by adjust_frame_for_plc(), chanspy_ds_free(), clear_dialed_interfaces(), queue_transfer_fixup(), speech_background(), speech_destroy(), stop_mixmonitor_exec(), and try_calling().

01531 {
01532    struct ast_datastore *datastore2 = NULL;
01533    int res = -1;
01534 
01535    /* Find our position and remove ourselves */
01536    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, entry) {
01537       if (datastore2 == datastore) {
01538          AST_LIST_REMOVE_CURRENT(&chan->datastores, entry);
01539          res = 0;
01540          break;
01541       }
01542    }
01543    AST_LIST_TRAVERSE_SAFE_END
01544 
01545    return res;
01546 }

int ast_channel_defer_dtmf ( struct ast_channel chan  ) 

Set defer DTMF flag on channel.

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

References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.

Referenced by __adsi_transmit_messages(), and find_cache().

01077 {
01078    int pre = 0;
01079 
01080    if (chan) {
01081       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
01082       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
01083    }
01084    return pre;
01085 }

void ast_channel_free ( struct ast_channel  ) 

Free a channel structure.

Definition at line 1355 of file channel.c.

References ast_channel::alertpipe, ast_app_group_discard(), ast_cdr_discard(), ast_channel_datastore_free(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_unlock, ast_copy_string(), ast_device_state_changed_literal(), AST_FLAG_IN_CHANNEL_LIST, ast_frfree, ast_jb_destroy(), AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_REMOVE_HEAD, AST_LIST_UNLOCK, ast_log(), ast_moh_cleanup(), ast_mutex_destroy(), ast_string_field_free_memory, ast_test_flag, ast_translator_free_path(), ast_var_delete(), ast_channel::cdr, ast_channel::cid, ast_channel::datastores, ast_datastore::entry, f, free, free_cid(), ast_channel::lock, LOG_DEBUG, ast_channel::monitor, ast_channel::music_state, ast_channel::name, name, option_debug, ast_channel::pbx, ast_channel::readq, ast_channel::readtrans, ast_channel::sched, sched_context_destroy(), ast_channel_monitor::stop, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel::varshead, and ast_channel::writetrans.

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

01356 {
01357    int fd;
01358    struct ast_var_t *vardata;
01359    struct ast_frame *f;
01360    struct varshead *headp;
01361    struct ast_datastore *datastore = NULL;
01362    char name[AST_CHANNEL_NAME], *dashptr;
01363    int inlist;
01364    
01365    headp=&chan->varshead;
01366    
01367    inlist = ast_test_flag(chan, AST_FLAG_IN_CHANNEL_LIST);
01368    if (inlist) {
01369       AST_LIST_LOCK(&channels);
01370       if (!AST_LIST_REMOVE(&channels, chan, chan_list)) {
01371          if (option_debug)
01372             ast_log(LOG_DEBUG, "Unable to find channel in list to free. Assuming it has already been done.\n");
01373       }
01374       /* Lock and unlock the channel just to be sure nobody has it locked still
01375          due to a reference retrieved from the channel list. */
01376       ast_channel_lock(chan);
01377       ast_channel_unlock(chan);
01378    }
01379 
01380    /* Get rid of each of the data stores on the channel */
01381    ast_channel_lock(chan);
01382    while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
01383       /* Free the data store */
01384       ast_channel_datastore_free(datastore);
01385    ast_channel_unlock(chan);
01386 
01387    /* Lock and unlock the channel just to be sure nobody has it locked still
01388       due to a reference that was stored in a datastore. (i.e. app_chanspy) */
01389    ast_channel_lock(chan);
01390    ast_channel_unlock(chan);
01391 
01392    if (chan->tech_pvt) {
01393       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
01394       free(chan->tech_pvt);
01395    }
01396 
01397    if (chan->sched)
01398       sched_context_destroy(chan->sched);
01399 
01400    ast_copy_string(name, chan->name, sizeof(name));
01401    if ((dashptr = strrchr(name, '-'))) {
01402       *dashptr = '\0';
01403    }
01404 
01405    /* Stop monitoring */
01406    if (chan->monitor)
01407       chan->monitor->stop( chan, 0 );
01408 
01409    /* If there is native format music-on-hold state, free it */
01410    if (chan->music_state)
01411       ast_moh_cleanup(chan);
01412 
01413    /* Free translators */
01414    if (chan->readtrans)
01415       ast_translator_free_path(chan->readtrans);
01416    if (chan->writetrans)
01417       ast_translator_free_path(chan->writetrans);
01418    if (chan->pbx)
01419       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
01420    free_cid(&chan->cid);
01421    /* Close pipes if appropriate */
01422    if ((fd = chan->alertpipe[0]) > -1)
01423       close(fd);
01424    if ((fd = chan->alertpipe[1]) > -1)
01425       close(fd);
01426    if ((fd = chan->timingfd) > -1)
01427       close(fd);
01428    while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
01429       ast_frfree(f);
01430    
01431    /* loop over the variables list, freeing all data and deleting list items */
01432    /* no need to lock the list, as the channel is already locked */
01433    
01434    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
01435       ast_var_delete(vardata);
01436 
01437    ast_app_group_discard(chan);
01438 
01439    /* Destroy the jitterbuffer */
01440    ast_jb_destroy(chan);
01441 
01442    if (chan->cdr) {
01443       ast_cdr_discard(chan->cdr);
01444       chan->cdr = NULL;
01445    }
01446    
01447    ast_mutex_destroy(&chan->lock);
01448 
01449    ast_string_field_free_memory(chan);
01450    free(chan);
01451    if (inlist)
01452       AST_LIST_UNLOCK(&channels);
01453 
01454    ast_device_state_changed_literal(name);
01455 }

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 4063 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(), ast_var_t::entries, LOG_DEBUG, option_debug, and ast_channel::varshead.

Referenced by __ast_request_and_dial(), agent_call(), ast_call_forward(), begin_dial(), feature_request_and_dial(), findmeexec(), ring_entry(), and wait_for_answer().

04064 {
04065    struct ast_var_t *current, *newvar;
04066    const char *varname;
04067 
04068    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
04069       int vartype = 0;
04070 
04071       varname = ast_var_full_name(current);
04072       if (!varname)
04073          continue;
04074 
04075       if (varname[0] == '_') {
04076          vartype = 1;
04077          if (varname[1] == '_')
04078             vartype = 2;
04079       }
04080 
04081       switch (vartype) {
04082       case 1:
04083          newvar = ast_var_assign(&varname[1], ast_var_value(current));
04084          if (newvar) {
04085             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
04086             if (option_debug)
04087                ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
04088          }
04089          break;
04090       case 2:
04091          newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
04092          if (newvar) {
04093             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
04094             if (option_debug)
04095                ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
04096          }
04097          break;
04098       default:
04099          if (option_debug)
04100             ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
04101          break;
04102       }
04103    }
04104 }

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

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

Referenced by app_exec(), ast_channel_bridge(), check_compat(), park_exec(), and wait_for_answer().

03904 {
03905    int src;
03906    int dst;
03907    int use_slin;
03908 
03909    if (chan->readformat == peer->writeformat && chan->writeformat == peer->readformat) {
03910       /* Already compatible!  Moving on ... */
03911       return 0;
03912    }
03913 
03914    /* Set up translation from the chan to the peer */
03915    src = chan->nativeformats;
03916    dst = peer->nativeformats;
03917    if (ast_translator_best_choice(&dst, &src) < 0) {
03918       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
03919       return -1;
03920    }
03921 
03922    /* if the best path is not 'pass through', then
03923       transcoding is needed; if desired, force transcode path
03924       to use SLINEAR between channels, but only if there is
03925       no direct conversion available */
03926    if ((src != dst) && ast_opt_transcode_via_slin &&
03927        (ast_translate_path_steps(dst, src) != 1))
03928       dst = AST_FORMAT_SLINEAR;
03929    if (ast_set_read_format(chan, dst) < 0) {
03930       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
03931       return -1;
03932    }
03933    if (ast_set_write_format(peer, dst) < 0) {
03934       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst);
03935       return -1;
03936    }
03937 
03938    /* Set up translation from the peer to the chan */
03939    src = peer->nativeformats;
03940    dst = chan->nativeformats;
03941    if (ast_translator_best_choice(&dst, &src) < 0) {
03942       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst);
03943       return -1;
03944    }
03945 
03946    /* if the best path is not 'pass through', then
03947     * transcoding is needed; if desired, force transcode path
03948     * to use SLINEAR between channels, but only if there is
03949     * no direct conversion available. If generic PLC is
03950     * desired, then transcoding via SLINEAR is a requirement
03951     */
03952    use_slin = (src == AST_FORMAT_SLINEAR || dst == AST_FORMAT_SLINEAR);
03953    if ((src != dst) && (ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
03954        (ast_translate_path_steps(dst, src) != 1 || use_slin))
03955       dst = AST_FORMAT_SLINEAR;
03956    if (ast_set_read_format(peer, dst) < 0) {
03957       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst);
03958       return -1;
03959    }
03960    if (ast_set_write_format(chan, dst) < 0) {
03961       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst);
03962       return -1;
03963    }
03964    return 0;
03965 }

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 3967 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, ast_channel::masq, ast_channel::masqr, ast_channel::name, option_debug, and ast_channel::tech.

Referenced by ast_async_goto(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), handle_invite_replaces(), iax_park(), masq_park_call(), misdn_attempt_transfer(), pickup_do(), and sip_park().

03968 {
03969    int res = -1;
03970    struct ast_channel *final_orig, *final_clone, *base;
03971 
03972 retrymasq:
03973    final_orig = original;
03974    final_clone = clone;
03975 
03976    ast_channel_lock(original);
03977    while (ast_channel_trylock(clone)) {
03978       ast_channel_unlock(original);
03979       usleep(1);
03980       ast_channel_lock(original);
03981    }
03982 
03983    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
03984       and if so, we don't really want to masquerade it, but its proxy */
03985    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
03986       final_orig = original->_bridge;
03987 
03988    if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone))
03989       final_clone = clone->_bridge;
03990    
03991    if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) {
03992       final_clone = base;
03993    }
03994 
03995    if ((final_orig != original) || (final_clone != clone)) {
03996       /* Lots and lots of deadlock avoidance.  The main one we're competing with
03997        * is ast_write(), which locks channels recursively, when working with a
03998        * proxy channel. */
03999       if (ast_channel_trylock(final_orig)) {
04000          ast_channel_unlock(clone);
04001          ast_channel_unlock(original);
04002          goto retrymasq;
04003       }
04004       if (ast_channel_trylock(final_clone)) {
04005          ast_channel_unlock(final_orig);
04006          ast_channel_unlock(clone);
04007          ast_channel_unlock(original);
04008          goto retrymasq;
04009       }
04010       ast_channel_unlock(clone);
04011       ast_channel_unlock(original);
04012       original = final_orig;
04013       clone = final_clone;
04014    }
04015 
04016    if (original == clone) {
04017       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
04018       ast_channel_unlock(clone);
04019       ast_channel_unlock(original);
04020       return -1;
04021    }
04022 
04023    if (option_debug)
04024       ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
04025          clone->name, original->name);
04026 
04027    if (!original->masqr && !original->masq && !clone->masq && !clone->masqr) {
04028       original->masq = clone;
04029       clone->masqr = original;
04030       ast_queue_frame(original, &ast_null_frame);
04031       ast_queue_frame(clone, &ast_null_frame);
04032       if (option_debug)
04033          ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
04034       res = 0;
04035 
04036    } else if (original->masq) {
04037       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
04038          original->masq->name, original->name);
04039    } else if (original->masqr) {
04040       /* not yet as a previously planned masq hasn't yet happened */
04041       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
04042          original->name, original->masqr->name);
04043    } else if (clone->masq) {
04044       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
04045          clone->masq->name, clone->name);
04046    } else { /* (clone->masqr) */
04047       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
04048          clone->name, clone->masqr->name);
04049    }
04050 
04051    ast_channel_unlock(clone);
04052    ast_channel_unlock(original);
04053 
04054    return res;
04055 }

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

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

03480 {
03481    switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */
03482    {
03483    case 0:
03484       return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
03485    case AST_CONTROL_HANGUP:
03486       return "Hangup";
03487    case AST_CONTROL_RING:
03488       return "Local Ring";
03489    case AST_CONTROL_RINGING:
03490       return "Remote end Ringing";
03491    case AST_CONTROL_ANSWER:
03492       return "Remote end has Answered";
03493    case AST_CONTROL_BUSY:
03494       return "Remote end is Busy";
03495    case AST_CONTROL_CONGESTION:
03496       return "Congestion (circuits busy)";
03497    default:
03498       return "Unknown Reason!!";
03499    }
03500 }

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

References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_verbose(), chanlist::list, 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().

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

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

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

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

03892 {
03893    if (chan->tech->send_html)
03894       return chan->tech->send_html(chan, subclass, data, datalen);
03895    return -1;
03896 }

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

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

Definition at line 3898 of file channel.c.

References ast_channel_sendhtml(), and AST_HTML_URL.

Referenced by sendurl_exec().

03899 {
03900    return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
03901 }

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

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 5028 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(), dahdi_hangup(), func_channel_write(), func_channel_write_real(), handle_tddmode(), play_record_review(), reset_volumes(), rpt(), set_listen_volume(), set_talk_volume(), and vm_forwardoptions().

05029 {
05030    int res;
05031 
05032    if (chan->tech->setoption) {
05033       res = chan->tech->setoption(chan, option, data, datalen);
05034       if (res < 0)
05035          return res;
05036    } else {
05037       errno = ENOSYS;
05038       return -1;
05039    }
05040    if (block) {
05041       /* XXX Implement blocking -- just wait for our option frame reply, discarding
05042          intermediate packets. XXX */
05043       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
05044       return -1;
05045    }
05046    return 0;
05047 }

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

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

Referenced by action_timeout(), and timeout_write().

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

struct ast_silence_generator* ast_channel_start_silence_generator ( struct ast_channel chan  ) 

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 5373 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_channel::name, ast_silence_generator::old_write_format, option_debug, silence_generator, and ast_channel::writeformat.

Referenced by __ast_play_and_record(), ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), waitforring_exec(), and waitforsilence_exec().

05374 {
05375    struct ast_silence_generator *state;
05376 
05377    if (!(state = ast_calloc(1, sizeof(*state)))) {
05378       return NULL;
05379    }
05380 
05381    state->old_write_format = chan->writeformat;
05382 
05383    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
05384       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
05385       free(state);
05386       return NULL;
05387    }
05388 
05389    ast_activate_generator(chan, &silence_generator, state);
05390 
05391    if (option_debug)
05392       ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
05393 
05394    return state;
05395 }

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

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

Referenced by __ast_play_and_record(), ast_bridge_call(), ast_dtmf_stream(), ast_readstring_full(), ast_safe_sleep_conditional(), channel_spy(), waitforring_exec(), and waitforsilence_exec().

05398 {
05399    if (!state)
05400       return;
05401 
05402    ast_deactivate_generator(chan);
05403 
05404    if (option_debug)
05405       ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
05406 
05407    if (ast_set_write_format(chan, state->old_write_format) < 0)
05408       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
05409 
05410    free(state);
05411 }

int ast_channel_supports_html ( struct ast_channel channel  ) 

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

Definition at line 3886 of file channel.c.

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

Referenced by sendurl_exec().

03887 {
03888    return (chan->tech->send_html) ? 1 : 0;
03889 }

void ast_channel_undefer_dtmf ( struct ast_channel chan  ) 

Unset defer DTMF flag on channel.

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

Definition at line 1088 of file channel.c.

References ast_clear_flag, and AST_FLAG_DEFER_DTMF.

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

01089 {
01090    if (chan)
01091       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
01092 }

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 529 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(), free, chanlist::list, LOG_DEBUG, option_debug, option_verbose, chanlist::tech, ast_channel_tech::type, and VERBOSE_PREFIX_2.

Referenced by __unload_module(), and unload_module().

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

struct ast_channel* ast_channel_walk_locked ( const struct ast_channel prev  ) 

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 1204 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(), next_channel(), pickup_by_exten(), pickup_by_mark(), and softhangup_exec().

01205 {
01206    return channel_find_locked(prev, NULL, 0, NULL, NULL);
01207 }

int ast_channel_whisper_feed ( struct ast_channel chan,
struct ast_frame f 
)

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

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

int ast_channel_whisper_start ( struct ast_channel chan  ) 

Begin 'whispering' onto a channel.

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

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

void ast_channel_whisper_stop ( struct ast_channel chan  ) 

Stop 'whispering' onto a channel.

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

struct ast_variable* ast_channeltype_list ( void   ) 

return an ast_variable list of channeltypes

Definition at line 163 of file channel.c.

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

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

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

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

Referenced by __ast_read(), _macro_exec(), action_redirect(), agent_indicate(), agi_handle_command(), announce_thread(), app_exec(), ast_answer(), ast_bridge_call(), ast_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_indicate_data(), ast_readstring_full(), ast_recvtext(), ast_rtp_bridge(), ast_sendtext(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), ast_write(), bridge_native_loop(), builtin_atxfer(), channel_spy(), common_exec(), conf_run(), dahdi_sendtext(), dahdi_setoption(), deadagi_exec(), feature_request_and_dial(), findmeexec(), handle_sendimage(), local_fixup(), pbx_exec(), rpt(), run_agi(), and wait_for_answer().

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

void ast_deactivate_generator ( struct ast_channel chan  ) 

Deactive an active generator

Definition at line 1774 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_clear_flag, AST_FLAG_WRITE_INT, AST_GENERATOR_FD, ast_settimeout(), ast_channel::fds, ast_channel::generator, ast_channel::generatordata, and ast_generator::release.

Referenced by __ast_read(), app_exec(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_playtones_stop(), ast_quiet_chan(), ast_read_generator_actions(), ast_tonepair_stop(), ast_write(), cb_events(), channel_spy(), generator_force(), local_ast_moh_stop(), old_milliwatt_exec(), and wait_for_answer().

01775 {
01776    ast_channel_lock(chan);
01777    if (chan->generatordata) {
01778       if (chan->generator && chan->generator->release)
01779          chan->generator->release(chan, chan->generatordata);
01780       chan->generatordata = NULL;
01781       chan->generator = NULL;
01782       chan->fds[AST_GENERATOR_FD] = -1;
01783       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
01784       ast_settimeout(chan, 0, NULL, NULL);
01785    }
01786    ast_channel_unlock(chan);
01787 }

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.

Note:
Assumes channel will be locked when called

Definition at line 4157 of file channel.c.

References ast_channel::_softhangup, ast_channel::_state, ast_channel::adsicpe, ast_channel::alertpipe, ast_app_group_update(), ast_bridged_channel(), ast_cause2str(), ast_channel_free(), ast_channel_lock, ast_channel_unlock, AST_CONTROL_SRCCHANGE, ast_copy_string(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_OUTGOING, 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_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_MAX_FDS, ast_null_frame, ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_string_field_set, ast_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::cdr, ast_datastore_info::chan_fixup, ast_channel::cid, clone_variables(), ast_datastore::data, ast_channel::datastores, ast_datastore::entry, errno, ast_channel::fdno, ast_channel::fds, ast_channel_tech::fixup, free_translation(), ast_channel_tech::hangup, ast_datastore::info, ast_channel::language, language, ast_channel::lock, LOG_DEBUG, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, musicclass, name, ast_channel::name, ast_channel::nativeformats, option_debug, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, report_new_callerid(), t, ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel_tech::type, ast_cdr::uniqueid, ast_channel::uniqueid, ast_channel::visible_indication, ast_channel::whentohangup, and ast_channel::writeformat.

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

04158 {
04159    int x,i;
04160    int res=0;
04161    int origstate;
04162    struct ast_frame *cur;
04163    const struct ast_channel_tech *t;
04164    void *t_pvt;
04165    struct ast_callerid tmpcid;
04166    struct ast_channel *clone = original->masq;
04167    struct ast_channel *bridged;
04168    struct ast_cdr *cdr;
04169    int rformat = original->readformat;
04170    int wformat = original->writeformat;
04171    char newn[100];
04172    char orig[100];
04173    char masqn[100];
04174    char zombn[100];
04175 
04176    if (option_debug > 3)
04177       ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
04178          clone->name, clone->_state, original->name, original->_state);
04179 
04180    /* XXX This operation is a bit odd.  We're essentially putting the guts of
04181     * the clone channel into the original channel.  Start by killing off the
04182     * original channel's backend.  While the features are nice, which is the
04183     * reason we're keeping it, it's still awesomely weird. XXX */
04184 
04185    /* We need the clone's lock, too */
04186    ast_channel_lock(clone);
04187 
04188    if (option_debug > 1)
04189       ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock);
04190 
04191    /* Having remembered the original read/write formats, we turn off any translation on either
04192       one */
04193    free_translation(clone);
04194    free_translation(original);
04195 
04196 
04197    /* Unlink the masquerade */
04198    original->masq = NULL;
04199    clone->masqr = NULL;
04200    
04201    /* Save the original name */
04202    ast_copy_string(orig, original->name, sizeof(orig));
04203    /* Save the new name */
04204    ast_copy_string(newn, clone->name, sizeof(newn));
04205    /* Create the masq name */
04206    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
04207       
04208    /* Copy the name from the clone channel */
04209    ast_string_field_set(original, name, newn);
04210 
04211    /* Mangle the name of the clone channel */
04212    ast_string_field_set(clone, name, masqn);
04213    
04214    /* Notify any managers of the change, first the masq then the other */
04215    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
04216    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
04217 
04218    /* Swap the technologies */   
04219    t = original->tech;
04220    original->tech = clone->tech;
04221    clone->tech = t;
04222 
04223    /* Swap the cdrs */
04224    cdr = original->cdr;
04225    /* swap cdr uniqueid between channels, to get cdr uniqueid = channel uniqueid */
04226    ast_copy_string(clone->cdr->uniqueid, cdr->uniqueid, sizeof(cdr->uniqueid));
04227    original->cdr = clone->cdr;
04228    clone->cdr = cdr;
04229 
04230    t_pvt = original->tech_pvt;
04231    original->tech_pvt = clone->tech_pvt;
04232    clone->tech_pvt = t_pvt;
04233 
04234    /* Swap the alertpipes */
04235    for (i = 0; i < 2; i++) {
04236       x = original->alertpipe[i];
04237       original->alertpipe[i] = clone->alertpipe[i];
04238       clone->alertpipe[i] = x;
04239    }
04240 
04241    /* 
04242     * Swap the readq's.  The end result should be this:
04243     *
04244     *  1) All frames should be on the new (original) channel.
04245     *  2) Any frames that were already on the new channel before this
04246     *     masquerade need to be at the end of the readq, after all of the
04247     *     frames on the old (clone) channel.
04248     *  3) The alertpipe needs to get poked for every frame that was already
04249     *     on the new channel, since we are now using the alert pipe from the
04250     *     old (clone) channel.
04251     */
04252    {
04253       AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
04254       AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
04255 
04256       AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
04257       AST_LIST_APPEND_LIST(&original->readq, &clone->readq, frame_list);
04258 
04259       while ((cur = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
04260          AST_LIST_INSERT_TAIL(&original->readq, cur, frame_list);
04261          if (original->alertpipe[1] > -1) {
04262             int poke = 0;
04263 
04264             if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) {
04265                ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
04266             }
04267          }
04268       }
04269    }
04270 
04271    /* Swap the raw formats */
04272    x = original->rawreadformat;
04273    original->rawreadformat = clone->rawreadformat;
04274    clone->rawreadformat = x;
04275    x = original->rawwriteformat;
04276    original->rawwriteformat = clone->rawwriteformat;
04277    clone->rawwriteformat = x;
04278 
04279    clone->_softhangup = AST_SOFTHANGUP_DEV;
04280 
04281    /* And of course, so does our current state.  Note we need not
04282       call ast_setstate since the event manager doesn't really consider
04283       these separate.  We do this early so that the clone has the proper
04284       state of the original channel. */
04285    origstate = original->_state;
04286    original->_state = clone->_state;
04287    clone->_state = origstate;
04288 
04289    if (clone->tech->fixup){
04290       res = clone->tech->fixup(original, clone);
04291       if (res)
04292          ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
04293    }
04294 
04295    /* Start by disconnecting the original's physical side */
04296    if (clone->tech->hangup)
04297       res = clone->tech->hangup(clone);
04298    if (res) {
04299       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
04300       ast_channel_unlock(clone);
04301       return -1;
04302    }
04303    
04304    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
04305    /* Mangle the name of the clone channel */
04306    ast_string_field_set(clone, name, zombn);
04307    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid);
04308 
04309    /* Update the type. */
04310    t_pvt = original->monitor;
04311    original->monitor = clone->monitor;
04312    clone->monitor = t_pvt;
04313    
04314    /* Keep the same language.  */
04315    ast_string_field_set(original, language, clone->language);
04316    /* Copy the FD's other than the generator fd */
04317    for (x = 0; x < AST_MAX_FDS; x++) {
04318       if (x != AST_GENERATOR_FD)
04319          original->fds[x] = clone->fds[x];
04320    }
04321 
04322    ast_app_group_update(clone, original);
04323    /* Move data stores over */
04324    if (AST_LIST_FIRST(&clone->datastores)) {
04325       struct ast_datastore *ds;
04326       /* We use a safe traversal here because some fixup routines actually
04327        * remove the datastore from the list and free them.
04328        */
04329       AST_LIST_TRAVERSE_SAFE_BEGIN(&clone->datastores, ds, entry) {
04330          if (ds->info->chan_fixup)
04331             ds->info->chan_fixup(ds->data, clone, original);
04332       }
04333       AST_LIST_TRAVERSE_SAFE_END;
04334       AST_LIST_APPEND_LIST(&original->datastores, &clone->datastores, entry);
04335    }
04336 
04337    clone_variables(original, clone);
04338    /* Presense of ADSI capable CPE follows clone */
04339    original->adsicpe = clone->adsicpe;
04340    /* Bridge remains the same */
04341    /* CDR fields remain the same */
04342    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
04343    /* Application and data remain the same */
04344    /* Clone exception  becomes real one, as with fdno */
04345    ast_set_flag(original, ast_test_flag(clone, AST_FLAG_OUTGOING | AST_FLAG_EXCEPTION));
04346    original->fdno = clone->fdno;
04347    /* Schedule context remains the same */
04348    /* Stream stuff stays the same */
04349    /* Keep the original state.  The fixup code will need to work with it most likely */
04350 
04351    /* Just swap the whole structures, nevermind the allocations, they'll work themselves
04352       out. */
04353    tmpcid = original->cid;
04354    original->cid = clone->cid;
04355    clone->cid = tmpcid;
04356    report_new_callerid(original);
04357 
04358    /* Restore original timing file descriptor */
04359    original->fds[AST_TIMING_FD] = original->timingfd;
04360    
04361    /* Our native formats are different now */
04362    original->nativeformats = clone->nativeformats;
04363    
04364    /* Context, extension, priority, app data, jump table,  remain the same */
04365    /* pvt switches.  pbx stays the same, as does next */
04366    
04367    /* Set the write format */
04368    ast_set_write_format(original, wformat);
04369 
04370    /* Set the read format */
04371    ast_set_read_format(original, rformat);
04372 
04373    /* Copy the music class */
04374    ast_string_field_set(original, musicclass, clone->musicclass);
04375 
04376    /* Copy whentohangup time */
04377    original->whentohangup = clone->whentohangup;
04378 
04379    if (option_debug)
04380       ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
04381 
04382    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
04383       can fix up everything as best as possible */
04384    if (original->tech->fixup) {
04385       res = original->tech->fixup(clone, original);
04386       if (res) {
04387          ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
04388             original->tech->type, original->name);
04389          ast_channel_unlock(clone);
04390          return -1;
04391       }
04392    } else
04393       ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
04394          original->tech->type, original->name);
04395 
04396    /* 
04397     * If an indication is currently playing, maintain it on the channel 
04398     * that is taking the place of original 
04399     *
04400     * This is needed because the masquerade is swapping out in the internals
04401     * of this channel, and the new channel private data needs to be made
04402     * aware of the current visible indication (RINGING, CONGESTION, etc.)
04403     */
04404    if (original->visible_indication) {
04405       ast_indicate(original, original->visible_indication);
04406    }
04407    
04408    /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
04409       a zombie so nothing tries to touch it.  If it's already been marked as a
04410       zombie, then free it now (since it already is considered invalid). */
04411    if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) {
04412       if (option_debug)
04413          ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name);
04414       ast_channel_unlock(clone);
04415       manager_event(EVENT_FLAG_CALL, "Hangup",
04416          "Channel: %s\r\n"
04417          "Uniqueid: %s\r\n"
04418          "Cause: %d\r\n"
04419          "Cause-txt: %s\r\n",
04420          clone->name,
04421          clone->uniqueid,
04422          clone->hangupcause,
04423          ast_cause2str(clone->hangupcause)
04424          );
04425       ast_channel_free(clone);
04426    } else {
04427       if (option_debug)
04428          ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
04429       ast_set_flag(clone, AST_FLAG_ZOMBIE);
04430       ast_queue_frame(clone, &ast_null_frame);
04431       ast_channel_unlock(clone);
04432    }
04433    
04434    /* Signal any blocker */
04435    if (ast_test_flag(original, AST_FLAG_BLOCKING))
04436       pthread_kill(original->blocker, SIGURG);
04437    if (option_debug)
04438       ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state);
04439 
04440    if ((bridged = ast_bridged_channel(original))) {
04441       ast_channel_lock(bridged);
04442       ast_indicate(bridged, AST_CONTROL_SRCCHANGE);
04443       ast_channel_unlock(bridged);
04444    }
04445 
04446    ast_indicate(original, AST_CONTROL_SRCCHANGE);
04447 
04448    return 0;
04449 }

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

01436 {
01437    int x;
01438    int dummy=0;
01439 
01440    if (fd < 0)
01441       return 0;
01442    if (!start)
01443       start = &dummy;
01444    for (x = *start; x<max; x++)
01445       if (pfds[x].fd == fd) {
01446          if (x == *start)
01447             (*start)++;
01448          return pfds[x].revents;
01449       }
01450    return 0;
01451 }

struct ast_channel* ast_get_channel_by_exten_locked ( const char *  exten,
const char *  context 
)

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

Definition at line 1229 of file channel.c.

References channel_find_locked().

01230 {
01231    return channel_find_locked(NULL, NULL, 0, context, exten);
01232 }

struct ast_channel* ast_get_channel_by_name_locked ( const char *  chan  ) 

Get channel by name (locks channel).

Definition at line 1210 of file channel.c.

References channel_find_locked().

Referenced by action_getvar(), action_hangup(), action_redirect(), action_setcdruserfield(), action_setvar(), action_status(), action_timeout(), ast_async_goto_by_name(), ast_bridge_call(), asyncgoto_exec(), change_monitor_action(), do_pause_or_unpause(), get_zap_channel_locked(), handle_channelstatus(), handle_core_set_debug_channel(), handle_debugchan_deprecated(), handle_getvariablefull(), handle_hangup(), handle_nodebugchan_deprecated(), handle_showchan(), handle_showchan_deprecated(), handle_softhangup(), manager_park(), manager_play_dtmf(), park_call_full(), pbx_builtin_importvar(), start_monitor_action(), and stop_monitor_action().

01211 {
01212    return channel_find_locked(NULL, name, 0, NULL, NULL);
01213 }

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

Get channel by name prefix (locks channel).

Definition at line 1216 of file channel.c.

References channel_find_locked().

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

01217 {
01218    return channel_find_locked(NULL, name, namelen, NULL, NULL);
01219 }

struct ast_channel_tech* ast_get_channel_tech ( const char *  name  ) 

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

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

Referenced by ast_device_state().

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

ast_group_t ast_get_group ( const char *  s  ) 

Definition at line 5201 of file channel.c.

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

Referenced by _parse(), build_device(), build_gateway(), build_peer(), build_user(), func_channel_write_real(), process_dahdi(), and read_agent_config().

05202 {
05203    char *piece;
05204    char *c;
05205    int start=0, finish=0, x;
05206    ast_group_t group = 0;
05207 
05208    if (ast_strlen_zero(s))
05209       return 0;
05210 
05211    c = ast_strdupa(s);
05212    
05213    while ((piece = strsep(&c, ","))) {
05214       if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
05215          /* Range */
05216       } else if (sscanf(piece, "%30d", &start)) {
05217          /* Just one */
05218          finish = start;
05219       } else {
05220          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
05221          continue;
05222       }
05223       for (x = start; x <= finish; x++) {
05224          if ((x > 63) || (x < 0)) {
05225             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
05226          } else
05227             group |= ((ast_group_t) 1 << x);
05228       }
05229    }
05230    return group;
05231 }

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

References ast_assert, ast_audiohook_detach_list(), ast_autoservice_stop(), ast_cause2str(), ast_cdr_detach(), ast_cdr_end(), AST_CDR_FLAG_BRIDGED, AST_CDR_FLAG_DIALED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_NULL, ast_channel_free(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_closestream(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_IN_CHANNEL_LIST, AST_FLAG_ZOMBIE, AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, ast_log(), ast_set_flag, ast_test_flag, ast_channel::audiohooks, ast_channel::blocker, ast_channel::blockproc, ast_channel::cdr, ast_cdr::disposition, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, LOG_DEBUG, LOG_ERROR, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::name, option_debug, ast_generator::release, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::tech, ast_channel::uniqueid, and ast_channel::vstream.

Referenced by __ast_request_and_dial(), __oh323_new(), agent_hangup(), agent_read(), alsa_new(), answer_exec_run(), app_exec(), ast_async_goto(), ast_bridge_call_thread(), ast_call_forward(), ast_dial_destroy(), ast_dial_hangup(), ast_iax2_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), begin_dial(), build_conf(), builtin_atxfer(), chanavail_exec(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_run(), connect_link(), dahdi_handle_event(), dahdi_new(), do_hang(), do_idle_thread(), do_parking_thread(), feature_request_and_dial(), 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(), masq_park_call(), mgcp_new(), mgcp_ss(), monitor_dial(), nbs_new(), oss_new(), park_exec(), parkandannounce_exec(), phone_new(), pri_dchannel(), rpt(), rpt_call(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss_thread(), wait_for_answer(), and wait_for_winner().

01636 {
01637    int res = 0;
01638 
01639    /* Don't actually hang up a channel that will masquerade as someone else, or
01640       if someone is going to masquerade as us */
01641    ast_channel_lock(chan);
01642 
01643    if (chan->audiohooks) {
01644       ast_audiohook_detach_list(chan->audiohooks);
01645       chan->audiohooks = NULL;
01646    }
01647 
01648    ast_autoservice_stop(chan);
01649 
01650    if (chan->masq) {
01651       if (ast_do_masquerade(chan))
01652          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01653    }
01654 
01655    if (chan->masq) {
01656       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
01657       ast_channel_unlock(chan);
01658       return 0;
01659    }
01660    /* If this channel is one which will be masqueraded into something,
01661       mark it as a zombie already, so we know to free it later */
01662    if (chan->masqr) {
01663       ast_set_flag(chan, AST_FLAG_ZOMBIE);
01664       ast_channel_unlock(chan);
01665       return 0;
01666    }
01667    ast_channel_unlock(chan);
01668 
01669    AST_LIST_LOCK(&channels);
01670    if (!AST_LIST_REMOVE(&channels, chan, chan_list)) {
01671       ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n");
01672    }
01673    ast_clear_flag(chan, AST_FLAG_IN_CHANNEL_LIST);
01674    AST_LIST_UNLOCK(&channels);
01675 
01676    ast_channel_lock(chan);
01677    free_translation(chan);
01678    /* Close audio stream */
01679    if (chan->stream) {
01680       ast_closestream(chan->stream);
01681       chan->stream = NULL;
01682    }
01683    /* Close video stream */
01684    if (chan->vstream) {
01685       ast_closestream(chan->vstream);
01686       chan->vstream = NULL;
01687    }
01688    if (chan->sched) {
01689       sched_context_destroy(chan->sched);
01690       chan->sched = NULL;
01691    }
01692    
01693    if (chan->generatordata)   /* Clear any tone stuff remaining */
01694       chan->generator->release(chan, chan->generatordata);
01695    chan->generatordata = NULL;
01696    chan->generator = NULL;
01697    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01698       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
01699                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
01700                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
01701       ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0);
01702    }
01703    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
01704       if (option_debug)
01705          ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
01706       if (chan->tech->hangup)
01707          res = chan->tech->hangup(chan);
01708    } else {
01709       if (option_debug)
01710          ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
01711    }
01712          
01713    ast_channel_unlock(chan);
01714    manager_event(EVENT_FLAG_CALL, "Hangup",
01715          "Channel: %s\r\n"
01716          "Uniqueid: %s\r\n"
01717          "Cause: %d\r\n"
01718          "Cause-txt: %s\r\n",
01719          chan->name,
01720          chan->uniqueid,
01721          chan->hangupcause,
01722          ast_cause2str(chan->hangupcause)
01723          );
01724 
01725    if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 
01726       !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 
01727        (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) {
01728       ast_channel_lock(chan);
01729          
01730       ast_cdr_end(chan->cdr);
01731       ast_cdr_detach(chan->cdr);
01732       chan->cdr = NULL;
01733       ast_channel_unlock(chan);
01734    }
01735    
01736    ast_channel_free(chan);
01737 
01738    return res;
01739 }

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

References ast_indicate_data().

Referenced by __ast_play_and_record(), agent_request(), answer_trunk_chan(), ast_answer(), ast_bridge_call(), ast_channel_bridge(), ast_do_masquerade(), ast_dtmf_stream(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), conf_run(), disa_exec(), do_parking_thread(), feature_request_and_dial(), features_indicate(), finishup(), function_remote(), handle_frame(), handle_recordfile(), handle_request_refer(), local_attended_transfer(), mgcp_ss(), monitor_dial(), park_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_proceeding(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), rna(), rpt(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), sla_trunk_exec(), and wait_for_answer().

02728 {
02729    return ast_indicate_data(chan, condition, NULL, 0);
02730 }

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

Note:
If we compare the enumeration type, which does not have any negative constants, the compiler may optimize this code away. Therefore, we must perform an integer comparison here.

Definition at line 2767 of file channel.c.

References ast_channel::_state, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_END_OF_Q, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, AST_FLAG_ZOMBIE, ast_get_indication_tone(), ast_log(), ast_playtones_start(), ast_playtones_stop(), AST_STATE_UP, ast_test_flag, tone_zone_sound::data, ast_channel_tech::indicate, is_visible_indication(), LOG_DEBUG, ast_channel::name, option_debug, ast_channel::tech, ast_channel::visible_indication, and ast_channel::zone.

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

02769 {
02770    /* By using an enum, we'll get compiler warnings for values not handled 
02771     * in switch statements. */
02772    enum ast_control_frame_type condition = _condition;
02773    const struct tone_zone_sound *ts = NULL;
02774    int res = -1;
02775 
02776    ast_channel_lock(chan);
02777 
02778    /* Don't bother if the channel is about to go away, anyway. */
02779    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02780       ast_channel_unlock(chan);
02781       return -1;
02782    }
02783 
02784    if (chan->tech->indicate) {
02785       /* See if the channel driver can handle this condition. */
02786       res = chan->tech->indicate(chan, condition, data, datalen);
02787    }
02788 
02789    ast_channel_unlock(chan);
02790 
02791    if (chan->tech->indicate && !res) {
02792       /* The channel driver successfully handled this indication */
02793       if (is_visible_indication(condition)) {
02794          chan->visible_indication = condition;
02795       }
02796       return 0;
02797    }
02798 
02799    /* The channel driver does not support this indication, let's fake
02800     * it by doing our own tone generation if applicable. */
02801 
02802    /*!\note If we compare the enumeration type, which does not have any
02803     * negative constants, the compiler may optimize this code away.
02804     * Therefore, we must perform an integer comparison here. */
02805    if (_condition < 0) {
02806       /* Stop any tones that are playing */
02807       ast_playtones_stop(chan);
02808       return 0;
02809    }
02810 
02811    /* Handle conditions that we have tones for. */
02812    switch (condition) {
02813    case AST_CONTROL_RINGING:
02814       ts = ast_get_indication_tone(chan->zone, "ring");
02815       /* It is common practice for channel drivers to return -1 if trying
02816        * to indicate ringing on a channel which is up. The idea is to let the
02817        * core generate the ringing inband. However, we don't want the
02818        * warning message about not being able to handle the specific indication
02819        * to print nor do we want ast_indicate_data to return an "error" for this
02820        * condition
02821        */
02822       if (chan->_state == AST_STATE_UP) {
02823          res = 0;
02824       }
02825       break;
02826    case AST_CONTROL_BUSY:
02827       ts = ast_get_indication_tone(chan->zone, "busy");
02828       break;
02829    case AST_CONTROL_CONGESTION:
02830       ts = ast_get_indication_tone(chan->zone, "congestion");
02831       break;
02832    case AST_CONTROL_PROGRESS:
02833    case AST_CONTROL_PROCEEDING:
02834    case AST_CONTROL_VIDUPDATE:
02835    case AST_CONTROL_SRCUPDATE:
02836    case AST_CONTROL_SRCCHANGE:
02837    case AST_CONTROL_RADIO_KEY:
02838    case AST_CONTROL_RADIO_UNKEY:
02839    case AST_CONTROL_OPTION:
02840    case AST_CONTROL_WINK:
02841    case AST_CONTROL_FLASH:
02842    case AST_CONTROL_OFFHOOK:
02843    case AST_CONTROL_TAKEOFFHOOK:
02844    case AST_CONTROL_ANSWER:
02845    case AST_CONTROL_HANGUP:
02846    case AST_CONTROL_RING:
02847    case AST_CONTROL_HOLD:
02848    case AST_CONTROL_UNHOLD:
02849    case AST_CONTROL_END_OF_Q:
02850       /* Nothing left to do for these. */
02851       res = 0;
02852       break;
02853    }
02854 
02855    if (ts && ts->data[0]) {
02856       /* We have a tone to play, yay. */
02857       if (option_debug) {
02858             ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
02859       }
02860       res = ast_playtones_start(chan, 0, ts->data, 1);
02861       chan->visible_indication = condition;
02862    }
02863 
02864    if (res) {
02865       /* not handled */
02866       ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
02867    }
02868 
02869    return res;
02870 }

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

References ast_opt_internal_timing, and ast_channel::timingfd.

Referenced by add_sdp(), and ast_read_generator_actions().

02713 {
02714    return (ast_opt_internal_timing && chan->timingfd > -1);
02715 }

int ast_is_deferrable_frame ( const struct ast_frame frame  ) 

Should we keep this frame for later?

There are functions such as ast_safe_sleep which will service a channel to ensure that it does not have a large backlog of queued frames. When this happens, we want to hold on to specific frame types and just drop others. This function will tell if the frame we just read should be held onto.

Parameters:
frame The frame we just read
Return values:
1 frame should be kept
0 frame should be dropped

Definition at line 1241 of file channel.c.

References AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, and ast_frame::frametype.

Referenced by ast_safe_sleep_conditional(), autoservice_run(), and feature_request_and_dial().

01242 {
01243    /* Do not add a default entry in this switch statement.  Each new
01244     * frame type should be addressed directly as to whether it should
01245     * be queued up or not.
01246     */
01247    switch (frame->frametype) {
01248    case AST_FRAME_CONTROL:
01249    case AST_FRAME_TEXT:
01250    case AST_FRAME_IMAGE:
01251    case AST_FRAME_HTML:
01252       return 1;
01253 
01254    case AST_FRAME_DTMF_END:
01255    case AST_FRAME_DTMF_BEGIN:
01256    case AST_FRAME_VOICE:
01257    case AST_FRAME_VIDEO:
01258    case AST_FRAME_NULL:
01259    case AST_FRAME_IAX:
01260    case AST_FRAME_CNG:
01261    case AST_FRAME_MODEM:
01262       return 0;
01263    }
01264    return 0;
01265 }

int ast_plc_reload ( void   ) 

Reload genericplc configuration value from codecs.conf.

Implementation is in main/channel.c

Definition at line 5280 of file channel.c.

References ast_config_load(), AST_OPT_FLAG_GENERIC_PLC, ast_options, ast_set2_flag, ast_true(), ast_variable_browse(), and var.

Referenced by ast_channels_init().

05281 {
05282    struct ast_variable *var;
05283    struct ast_config *cfg = ast_config_load("codecs.conf");
05284    if (!cfg)
05285       return 0;
05286    for (var = ast_variable_browse(cfg, "plc"); var; var = var->next) {
05287       if (!strcasecmp(var->name, "genericplc")) {
05288          ast_set2_flag(&ast_options, ast_true(var->value), AST_OPT_FLAG_GENERIC_PLC);
05289       }
05290    }
05291    ast_config_destroy(cfg);
05292    return 0;
05293 }

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

print call- and pickup groups into buffer

Definition at line 5303 of file channel.c.

References first.

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

05304 {
05305    unsigned int i;
05306    int first=1;
05307    char num[3];
05308 
05309    buf[0] = '\0';
05310    
05311    if (!group) /* Return empty string if no group */
05312       return buf;
05313 
05314    for (i = 0; i <= 63; i++) {   /* Max group is 63 */
05315       if (group & ((ast_group_t) 1 << i)) {
05316             if (!first) {
05317             strncat(buf, ", ", buflen - strlen(buf) - 1);
05318          } else {
05319             first=0;
05320          }
05321          snprintf(num, sizeof(num), "%u", i);
05322          strncat(buf, num, buflen - strlen(buf) - 1);
05323       }
05324    }
05325    return buf;
05326 }

int ast_prod ( struct ast_channel chan  ) 

Send empty audio to prime a channel driver.

Definition at line 2997 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, ast_channel::name, option_debug, ast_channel::rawwriteformat, ast_frame::src, and ast_frame::subclass.

Referenced by ast_activate_generator().

02998 {
02999    struct ast_frame a = { AST_FRAME_VOICE };
03000    char nothing[128];
03001 
03002    /* Send an empty audio frame to get things moving */
03003    if (chan->_state != AST_STATE_UP) {
03004       if (option_debug)
03005          ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
03006       a.subclass = chan->rawwriteformat;
03007       a.data = nothing + AST_FRIENDLY_OFFSET;
03008       a.src = "ast_prod"; /* this better match check in ast_write */
03009       if (ast_write(chan, &a))
03010          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
03011    }
03012    return 0;
03013 }

int ast_queue_control ( struct ast_channel chan,
enum ast_control_frame_type  control 
)

Queue a control frame with payload.

Parameters:
chan channel to queue frame onto
control type of control frame
Returns:
zero on success, non-zero on failure

Definition at line 1053 of file channel.c.

References AST_FRAME_CONTROL, ast_queue_frame(), and f.

Referenced by __ast_read(), __dahdi_exception(), __oh323_update_info(), attempt_transfer(), auto_congest(), cb_events(), dahdi_handle_event(), dahdi_hangup(), gtalk_is_answered(), gtalk_ringing_ack(), handle_hd_hf(), handle_offhook_message(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_refer(), handle_soft_key_event_message(), handle_stimulus_message(), mgcp_call(), misdn_attempt_transfer(), nbs_call(), phone_call(), pickup_do(), process_sdp(), receive_digit(), send_cause2ast(), setup_rtp_connection(), skinny_call(), skinny_unhold(), ss_thread(), and update_state().

01054 {
01055    struct ast_frame f = { AST_FRAME_CONTROL, };
01056 
01057    f.subclass = control;
01058 
01059    return ast_queue_frame(chan, &f);
01060 }

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

References AST_FRAME_CONTROL, ast_queue_frame(), and f.

Referenced by dahdi_handle_event(), dahdi_hangup(), iax2_queue_control_data(), process_sdp(), and skinny_hold().

01065 {
01066    struct ast_frame f = { AST_FRAME_CONTROL, };
01067 
01068    f.subclass = control;
01069    f.data = (void *) data;
01070    f.datalen = datalen;
01071 
01072    return ast_queue_frame(chan, &f);
01073 }

int ast_queue_frame ( struct ast_channel chan,
struct ast_frame f 
)

Queue one or more frames to a channel's frame queue.

Parameters:
chan the channel to queue the frame(s) on
f the frame(s) to queue. Note that the frame(s) will be duplicated by this function. It is the responsibility of the caller to handle freeing the memory associated with the frame(s) being passed if necessary.
Return values:
0 success
non-zero failure

Definition at line 1030 of file channel.c.

References __ast_queue_frame().

Referenced by __ast_read(), __oh323_rtp_create(), __oh323_update_info(), agent_request(), alsa_call(), 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(), dahdi_queue_frame(), 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(), pri_queue_frame(), process_sdp(), queue_dtmf_readq(), receive_digit(), receive_message(), rpt_call(), and wakeup_sub().

01031 {
01032    return __ast_queue_frame(chan, fin, 0, NULL);
01033 }

int ast_queue_frame_head ( struct ast_channel chan,
struct ast_frame f 
)

Queue one or more frames to the head of a channel's frame queue.

Parameters:
chan the channel to queue the frame(s) on
f the frame(s) to queue. Note that the frame(s) will be duplicated by this function. It is the responsibility of the caller to handle freeing the memory associated with the frame(s) being passed if necessary.
Return values:
0 success
non-zero failure

Definition at line 1035 of file channel.c.

References __ast_queue_frame().

Referenced by __ast_read(), ast_autoservice_stop(), ast_safe_sleep_conditional(), and feature_request_and_dial().

01036 {
01037    return __ast_queue_frame(chan, fin, 1, NULL);
01038 }

int ast_queue_hangup ( struct ast_channel chan  ) 

Queue a hangup frame.

Definition at line 1041 of file channel.c.

References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, and f.

Referenced by __oh323_update_info(), __sip_autodestruct(), cleanup_connection(), console_hangup(), console_hangup_deprecated(), dahdi_handle_event(), dahdi_r2_on_call_disconnect(), gtalk_hangup_farend(), gtalk_is_answered(), handle_onhook_message(), handle_request_bye(), handle_request_cancel(), handle_response(), handle_response_invite(), handle_soft_key_event_message(), hangup_chan(), hangup_connection(), iax2_destroy(), iax2_queue_hangup(), local_fixup(), local_hangup(), mgcp_queue_hangup(), misdn_answer(), pri_hangup_all(), and retrans_pkt().

01042 {
01043    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
01044    /* Yeah, let's not change a lock-critical value without locking */
01045    if (!ast_channel_trylock(chan)) {
01046       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01047       ast_channel_unlock(chan);
01048    }
01049    return ast_queue_frame(chan, &f);
01050 }

struct ast_frame* ast_read ( struct ast_channel chan  ) 

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 2717 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_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(), channel_spy(), check_goto_on_transfer(), conf_exec(), conf_flush(), conf_run(), dahdi_bridge(), dictate_exec(), disa_exec(), do_idle_thread(), do_parking_thread(), do_waiting(), echo_exec(), feature_request_and_dial(), features_read(), find_cache(), handle_recordfile(), iax_park_thread(), ices_exec(), isAnsweringMachine(), masq_park_call(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), recordthread(), rpt(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), speech_background(), ss_thread(), wait_for_answer(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), and waitstream_core().

02718 {
02719    return __ast_read(chan, 0);
02720 }

struct ast_frame* ast_read_noaudio ( struct ast_channel chan  ) 

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

References __ast_read().

Referenced by conf_run().

02723 {
02724    return __ast_read(chan, 1);
02725 }

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

03828 {
03829    return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
03830 }

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

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

Referenced by ast_app_getdata_full(), and ast_readstring().

03833 {
03834    int pos = 0;   /* index in the buffer where we accumulate digits */
03835    int to = ftimeout;
03836 
03837    struct ast_silence_generator *silgen = NULL;
03838 
03839    /* Stop if we're a zombie or need a soft hangup */
03840    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03841       return -1;
03842    if (!len)
03843       return -1;
03844    for (;;) {
03845       int d;
03846       if (c->stream) {
03847          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
03848          ast_stopstream(c);
03849          if (!silgen && ast_opt_transmit_silence)
03850             silgen = ast_channel_start_silence_generator(c);
03851          usleep(1000);
03852          if (!d)
03853             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03854       } else {
03855          if (!silgen && ast_opt_transmit_silence)
03856             silgen = ast_channel_start_silence_generator(c);
03857          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03858       }
03859       if (d < 0) {
03860          ast_channel_stop_silence_generator(c, silgen);
03861          return -1;
03862       }
03863       if (d == 0) {
03864          s[pos]='\0';
03865          ast_channel_stop_silence_generator(c, silgen);
03866          return 1;
03867       }
03868       if (d == 1) {
03869          s[pos]='\0';
03870          ast_channel_stop_silence_generator(c, silgen);
03871          return 2;
03872       }
03873       if (!strchr(enders, d))
03874          s[pos++] = d;
03875       if (strchr(enders, d) || (pos >= len)) {
03876          s[pos]='\0';
03877          ast_channel_stop_silence_generator(c, silgen);
03878          return 0;
03879       }
03880       to = timeout;
03881    }
03882    /* Never reached */
03883    return 0;
03884 }

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

References ast_recvtext(), and free.

Referenced by handle_recvchar().

02873 {
02874    int c;
02875    char *buf = ast_recvtext(chan, timeout);
02876    if (buf == NULL)
02877       return -1;  /* error or timeout */
02878    c = *(unsigned char *)buf;
02879    free(buf);
02880    return c;
02881 }

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 2883 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(), and f.

Referenced by ast_recvchar(), and handle_recvtext().

02884 {
02885    int res, done = 0;
02886    char *buf = NULL;
02887    
02888    while (!done) {
02889       struct ast_frame *f;
02890       if (ast_check_hangup(chan))
02891          break;
02892       res = ast_waitfor(chan, timeout);
02893       if (res <= 0) /* timeout or error */
02894          break;
02895       timeout = res; /* update timeout */
02896       f = ast_read(chan);
02897       if (f == NULL)
02898          break; /* no frame */
02899       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
02900          done = 1;   /* force a break */
02901       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
02902          buf = ast_strndup((char *) f->data, f->datalen);   /* dup and break */
02903          done = 1;
02904       }
02905       ast_frfree(f);
02906    }
02907    return buf;
02908 }

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

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 3732 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, ast_channel_tech::requester, chanlist::tech, and ast_channel_tech::type.

Referenced by __ast_request_and_dial(), agent_request(), ast_call_forward(), attempt_reconnect(), begin_dial(), build_conf(), chanavail_exec(), conf_run(), connect_link(), feature_request_and_dial(), features_alloc(), findmeexec(), ring_entry(), rpt(), rpt_call(), rpt_tele_thread(), and wait_for_answer().

03733 {
03734    struct chanlist *chan;
03735    struct ast_channel *c;
03736    int capabilities;
03737    int fmt;
03738    int res;
03739    int foo;
03740    int videoformat = format & AST_FORMAT_VIDEO_MASK;
03741 
03742    if (!cause)
03743       cause = &foo;
03744    *cause = AST_CAUSE_NOTDEFINED;
03745 
03746    if (AST_LIST_LOCK(&channels)) {
03747       ast_log(LOG_WARNING, "Unable to lock channel list\n");
03748       return NULL;
03749    }
03750 
03751    AST_LIST_TRAVERSE(&backends, chan, list) {
03752       if (strcasecmp(type, chan->tech->type))
03753          continue;
03754 
03755       capabilities = chan->tech->capabilities;
03756       fmt = format & AST_FORMAT_AUDIO_MASK;
03757       res = ast_translator_best_choice(&fmt, &capabilities);
03758       if (res < 0) {
03759          ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
03760          *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03761          AST_LIST_UNLOCK(&channels);
03762          return NULL;
03763       }
03764       AST_LIST_UNLOCK(&channels);
03765       if (!chan->tech->requester)
03766          return NULL;
03767       
03768       if (!(c = chan->tech->requester(type, capabilities | videoformat, data, cause)))
03769          return NULL;
03770 
03771       /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
03772       return c;
03773    }
03774 
03775    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
03776    *cause = AST_CAUSE_NOSUCHDRIVER;
03777    AST_LIST_UNLOCK(&channels);
03778 
03779    return NULL;
03780 }

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

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

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

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_exten().

03728 {
03729    return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
03730 }

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 1335 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(), conf_run(), dictate_exec(), flash_exec(), function_ilink(), mgcp_ss(), milliwatt_exec(), moh0_exec(), moh1_exec(), old_milliwatt_exec(), park_call_exec(), pbx_builtin_answer(), pbx_builtin_wait(), play_tone_pair(), playtone(), privacy_exec(), receive_ademco_contact_id(), rpt_call(), rpt_exec(), rpt_tele_thread(), send_morse(), send_tone_telemetry(), skinny_ss(), ss_thread(), testclient_exec(), testserver_exec(), wait_for_hangup(), wait_interval(), and zapateller_exec().

01336 {
01337    return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
01338 }

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

References ast_channel_lock, ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_channel_unlock, ast_frfree, ast_frisolate(), ast_is_deferrable_frame(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_opt_transmit_silence, ast_queue_frame_head(), ast_read(), ast_waitfor(), f, and ast_channel::generatordata.

Referenced by __login_exec(), and ast_safe_sleep().

01269 {
01270    struct ast_frame *f;
01271    struct ast_silence_generator *silgen = NULL;
01272    int res = 0;
01273    AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
01274 
01275    AST_LIST_HEAD_INIT_NOLOCK(&deferred_frames);
01276 
01277    /* If no other generator is present, start silencegen while waiting */
01278    if (ast_opt_transmit_silence && !chan->generatordata) {
01279       silgen = ast_channel_start_silence_generator(chan);
01280    }
01281 
01282    while (ms > 0) {
01283       struct ast_frame *dup_f = NULL;
01284       if (cond && ((*cond)(data) == 0)) {
01285          break;
01286       }
01287       ms = ast_waitfor(chan, ms);
01288       if (ms < 0) {
01289          res = -1;
01290          break;
01291       }
01292       if (ms > 0) {
01293          f = ast_read(chan);
01294          if (!f) {
01295             res = -1;
01296             break;
01297          }
01298 
01299          if (!ast_is_deferrable_frame(f)) {
01300             ast_frfree(f);
01301             continue;
01302          }
01303          
01304          if ((dup_f = ast_frisolate(f))) {
01305             if (dup_f != f) {
01306                ast_frfree(f);
01307             }
01308             AST_LIST_INSERT_HEAD(&deferred_frames, dup_f, frame_list);
01309          }
01310       }
01311    }
01312 
01313    /* stop silgen if present */
01314    if (silgen) {
01315       ast_channel_stop_silence_generator(chan, silgen);
01316    }
01317 
01318    /* We need to free all the deferred frames, but we only need to
01319     * queue the deferred frames if there was no error and no
01320     * hangup was received
01321     */
01322    ast_channel_lock(chan);
01323    while ((f = AST_LIST_REMOVE_HEAD(&deferred_frames, frame_list))) {
01324       if (!res) {
01325          ast_queue_frame_head(chan, f);
01326       }
01327       ast_frfree(f);
01328    }
01329    ast_channel_unlock(chan);
01330 
01331    return res;
01332 }

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

References ast_malloc, and len().

Referenced by dahdi_new(), and features_new().

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

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

02988 {
02989    if (chan->tech->send_digit_begin) {
02990       ast_senddigit_begin(chan, digit);
02991       ast_safe_sleep(chan, AST_DEFAULT_EMULATE_DTMF_DURATION);
02992    }
02993    
02994    return ast_senddigit_end(chan, digit, AST_DEFAULT_EMULATE_DTMF_DURATION);
02995 }

int ast_senddigit_begin ( struct ast_channel chan,
char  digit 
)

Definition at line 2928 of file channel.c.

References ast_log(), ast_playtones_start(), LOG_DEBUG, ast_channel::name, 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().

02929 {
02930    /* Device does not support DTMF tones, lets fake
02931     * it by doing our own generation. */
02932    static const char* dtmf_tones[] = {
02933       "941+1336", /* 0 */
02934       "697+1209", /* 1 */
02935       "697+1336", /* 2 */
02936       "697+1477", /* 3 */
02937       "770+1209", /* 4 */
02938       "770+1336", /* 5 */
02939       "770+1477", /* 6 */
02940       "852+1209", /* 7 */
02941       "852+1336", /* 8 */
02942       "852+1477", /* 9 */
02943       "697+1633", /* A */
02944       "770+1633", /* B */
02945       "852+1633", /* C */
02946       "941+1633", /* D */
02947       "941+1209", /* * */
02948       "941+1477"  /* # */
02949    };
02950 
02951    if (!chan->tech->send_digit_begin)
02952       return 0;
02953 
02954    if (!chan->tech->send_digit_begin(chan, digit))
02955       return 0;
02956 
02957    if (digit >= '0' && digit <='9')
02958       ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
02959    else if (digit >= 'A' && digit <= 'D')
02960       ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
02961    else if (digit == '*')
02962       ast_playtones_start(chan, 0, dtmf_tones[14], 0);
02963    else if (digit == '#')
02964       ast_playtones_start(chan, 0, dtmf_tones[15], 0);
02965    else {
02966       /* not handled */
02967       if (option_debug)
02968          ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
02969    }
02970 
02971    return 0;
02972 }

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

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

02975 {
02976    int res = -1;
02977 
02978    if (chan->tech->send_digit_end)
02979       res = chan->tech->send_digit_end(chan, digit, duration);
02980 
02981    if (res && chan->generator)
02982       ast_playtones_stop(chan);
02983    
02984    return 0;
02985 }

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

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

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

Definition at line 2910 of file channel.c.

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

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

02911 {
02912    int res = 0;
02913 
02914    ast_channel_lock(chan);
02915    /* Stop if we're a zombie or need a soft hangup */
02916    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02917       ast_channel_unlock(chan);
02918       return -1;
02919    }
02920    CHECK_BLOCKING(chan);
02921    if (chan->tech->send_text)
02922       res = chan->tech->send_text(chan, text);
02923    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02924    ast_channel_unlock(chan);
02925    return res;
02926 }

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

References ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_strdup, ast_channel::cdr, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, free, and report_new_callerid().

Referenced by __ast_request_and_dial(), agent_call(), ast_call_forward(), callerid_write(), dahdi_read(), disa_exec(), feature_request_and_dial(), findmeexec(), handle_setcallerid(), lookupcidname_exec(), mgcp_ss(), privacy_exec(), read_config(), setcallerid_exec(), skinny_newcall(), ss_thread(), and wait_for_answer().

04452 {
04453    ast_channel_lock(chan);
04454 
04455    if (callerid) {
04456       if (chan->cid.cid_num)
04457          free(chan->cid.cid_num);
04458       chan->cid.cid_num = ast_strdup(callerid);
04459    }
04460    if (calleridname) {
04461       if (chan->cid.cid_name)
04462          free(chan->cid.cid_name);
04463       chan->cid.cid_name = ast_strdup(calleridname);
04464    }
04465    if (ani) {
04466       if (chan->cid.cid_ani)
04467          free(chan->cid.cid_ani);
04468       chan->cid.cid_ani = ast_strdup(ani);
04469    }
04470    if (chan->cdr) {
04471       ast_cdr_setcid(chan->cdr, chan);
04472    }
04473 
04474    report_new_callerid(chan);
04475 
04476    ast_channel_unlock(chan);
04477 }

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.

Parameters:
chan channel to change
format format to change to
Returns:
Returns 0 on success, -1 on failure

Definition at line 3467 of file channel.c.

References ast_channel::rawreadformat, ast_channel::readformat, ast_channel::readtrans, and set_format().

Referenced by __ast_play_and_record(), __login_exec(), __oh323_update_info(), agent_call(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_channel_make_compatible(), ast_do_masquerade(), attempt_reconnect(), background_detect_exec(), build_conf(), conf_run(), connect_link(), dictate_exec(), disa_exec(), do_waiting(), eagi_exec(), echo_exec(), gtalk_rtp_read(), handle_recordfile(), ices_exec(), isAnsweringMachine(), measurenoise(), mgcp_rtp_read(), oh323_rtp_read(), old_milliwatt_exec(), process_sdp(), rpt(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), and update_features().

03468 {
03469    return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
03470            &chan->readtrans, 0);
03471 }

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 5328 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_call_forward(), ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

05329 {
05330    struct ast_variable *cur;
05331 
05332    for (cur = vars; cur; cur = cur->next)
05333       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
05334 }

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.

Parameters:
chan channel to change
format new format for writing
Returns:
Returns 0 on success, -1 on failure

Definition at line 3473 of file channel.c.

References ast_channel::rawwriteformat, set_format(), ast_channel::writeformat, and ast_channel::writetrans.

Referenced by __login_exec(), __oh323_update_info(), agent_call(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_channel_make_compatible(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_do_masquerade(), ast_openstream_full(), ast_stopstream(), attempt_reconnect(), build_conf(), chanspy_exec(), conf_run(), connect_link(), disa_exec(), echo_exec(), extenspy_exec(), gtalk_rtp_read(), linear_alloc(), linear_release(), mgcp_rtp_read(), moh_alloc(), moh_files_release(), moh_release(), mp3_exec(), NBScat_exec(), oh323_rtp_read(), old_milliwatt_exec(), playtones_alloc(), playtones_release(), process_sdp(), rpt(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), tonepair_alloc(), tonepair_release(), and update_features().

03474 {
03475    return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
03476            &chan->writetrans, 1);
03477 }

int ast_setstate ( struct ast_channel chan,
enum  ast_channel_state 
)

Change the state of a channel.

Definition at line 4479 of file channel.c.

References ast_channel::_state, AST_CHANNEL_NAME, ast_copy_string(), ast_device_state_changed_literal(), ast_state2str(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, manager_event(), ast_channel::name, name, S_OR, and ast_channel::uniqueid.

Referenced by __ast_read(), __dahdi_exception(), __oh323_update_info(), agent_call(), alsa_answer(), ast_answer(), cb_events(), check_availability(), dahdi_answer(), dahdi_call(), dahdi_handle_event(), dahdi_indicate(), dahdi_read(), gtalk_call(), gtalk_newcall(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_response_invite(), handle_soft_key_event_message(), handle_stimulus_message(), iax2_call(), local_queue_frame(), mgcp_answer(), mgcp_call(), mgcp_ss(), misdn_call(), misdn_indication(), nbs_call(), nbs_hangup(), oh323_answer(), oss_answer(), pbx_builtin_busy(), pbx_builtin_congestion(), phone_answer(), phone_call(), phone_exception(), phone_hangup(), phone_write(), release_chan(), release_chan_early(), sip_answer(), skinny_answer(), skinny_call(), skinny_newcall(), ss_thread(), and update_state().

04480 {
04481    char name[AST_CHANNEL_NAME], *dashptr;
04482    int oldstate = chan->_state;
04483 
04484    if (oldstate == state)
04485       return 0;
04486 
04487    ast_copy_string(name, chan->name, sizeof(name));
04488    if ((dashptr = strrchr(name, '-'))) {
04489       *dashptr = '\0';
04490    }
04491 
04492    chan->_state = state;
04493    ast_device_state_changed_literal(name);
04494    /* setstate used to conditionally report Newchannel; this is no more */
04495    manager_event(EVENT_FLAG_CALL,
04496             "Newstate",
04497             "Channel: %s\r\n"
04498             "State: %s\r\n"
04499             "CallerID: %s\r\n"
04500             "CallerIDName: %s\r\n"
04501             "Uniqueid: %s\r\n",
04502             chan->name, ast_state2str(chan->_state),
04503             S_OR(chan->cid.cid_num, "<unknown>"),
04504             S_OR(chan->cid.cid_name, "<unknown>"),
04505             chan->uniqueid);
04506 
04507    return 0;
04508 }

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

Definition at line 2026 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_log(), 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(), ast_readaudio_callback(), and filestream_destructor().

02027 {
02028    int res = -1;
02029 #ifdef HAVE_DAHDI
02030    ast_channel_lock(c);
02031    if (c->timingfd > -1) {
02032       if (!func) {
02033          samples = 0;
02034          data = 0;
02035       }
02036       if (option_debug)
02037          ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
02038       res = ioctl(c->timingfd, DAHDI_TIMERCONFIG, &samples);
02039       c->timingfunc = func;
02040       c->timingdata = data;
02041    }
02042    ast_channel_unlock(c);
02043 #endif   
02044    return res;
02045 }

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

Referenced by handle_request_options().

00462 {
00463    return shutting_down;
00464 }

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.
reason an AST_SOFTHANGUP_* reason code
Returns:
Returns 0 regardless

Definition at line 1613 of file channel.c.

References ast_channel_lock, ast_channel_unlock, and ast_softhangup_nolock().

Referenced by __ast_module_user_hangup_all(), __login_exec(), __unload_module(), action_hangup(), agent_hangup(), agent_logoff(), agent_read(), ast_begin_shutdown(), ast_dial_join(), conf_free(), connect_link(), dahdi_handle_event(), 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(), and unload_module().

01614 {
01615    int res;
01616    ast_channel_lock(chan);
01617    res = ast_softhangup_nolock(chan, cause);
01618    ast_channel_unlock(chan);
01619    return res;
01620 }

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
reason an AST_SOFTHANGUP_* reason code

Definition at line 1599 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, ast_channel::name, and option_debug.

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

01600 {
01601    if (option_debug)
01602       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
01603    /* Inform channel driver that we need to be hung up, if it cares */
01604    chan->_softhangup |= cause;
01605    ast_queue_frame(chan, &ast_null_frame);
01606    /* Interrupt any poll call or such */
01607    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
01608       pthread_kill(chan->blocker, SIGURG);
01609    return 0;
01610 }

char* ast_state2str ( enum  ast_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 600 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, ast_threadstorage_get(), STATE2STR_BUFSIZE, and state2str_threadbuf.

Referenced by action_status(), agent_hangup(), ast_setstate(), 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().

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

int ast_str2cause ( const char *  name  ) 

Convert a symbolic hangup cause to number.

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

Definition at line 588 of file channel.c.

References causes.

Referenced by pbx_builtin_hangup().

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

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

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

Referenced by zapateller_exec().

05184 {
05185    int res;
05186 
05187    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
05188       return res;
05189 
05190    /* Give us some wiggle room */
05191    while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
05192       struct ast_frame *f = ast_read(chan);
05193       if (f)
05194          ast_frfree(f);
05195       else
05196          return -1;
05197    }
05198    return 0;
05199 }

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

Start a tone going

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

05166 {
05167    struct tonepair_def d = { 0, };
05168 
05169    d.freq1 = freq1;
05170    d.freq2 = freq2;
05171    d.duration = duration;
05172    d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */
05173    if (ast_activate_generator(chan, &tonepair, &d))
05174       return -1;
05175    return 0;
05176 }

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 5178 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

05179 {
05180    ast_deactivate_generator(chan);
05181 }

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.

Called by:

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

03810 {
03811    int res = -1;
03812 
03813    /* Stop if we're a zombie or need a soft hangup */
03814    ast_channel_lock(chan);
03815    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03816       if (chan->tech->transfer) {
03817          res = chan->tech->transfer(chan, dest);
03818          if (!res)
03819             res = 1;
03820       } else
03821          res = 0;
03822    }
03823    ast_channel_unlock(chan);
03824    return res;
03825 }

char* ast_transfercapability2str ( int  transfercapability  )  const

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 634 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(), dahdi_call(), dahdi_new(), misdn_call(), and oh323_call().

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

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 2010 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_idle_thread(), do_waiting(), echo_exec(), handle_recordfile(), ices_exec(), isAnsweringMachine(), measurenoise(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), recordthread(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), speech_background(), ss_thread(), wait_for_hangup(), waitforring_exec(), and waitstream_core().

02011 {
02012    int oldms = ms;   /* -1 if no timeout */
02013 
02014    ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
02015    if ((ms < 0) && (oldms < 0))
02016       ms = 0;
02017    return ms;
02018 }

struct ast_channel* ast_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.

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

References ast_waitfor_nandfds().

Referenced by ast_udptl_bridge(), autoservice_run(), bridge_native_loop(), dahdi_bridge(), feature_request_and_dial(), misdn_bridge(), monitor_dial(), rpt(), wait_for_answer(), and wait_for_winner().

02006 {
02007    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
02008 }

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

References ast_waitfor_nandfds().

Referenced by dundi_lookup_internal(), and dundi_precache_internal().

01846 {
01847    int winner = -1;
01848    ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
01849    return winner;
01850 }

struct ast_channel* ast_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.

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 1853 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_poll, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, ast_tvdiff_ms(), ast_tvnow(), CHECK_BLOCKING, errno, 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().

01855 {
01856    struct timeval start = { 0 , 0 };
01857    struct pollfd *pfds = NULL;
01858    int res;
01859    long rms;
01860    int x, y, max;
01861    int sz;
01862    time_t now = 0;
01863    long whentohangup = 0, diff;
01864    struct ast_channel *winner = NULL;
01865    struct fdmap {
01866       int chan;
01867       int fdno;
01868    } *fdmap = NULL;
01869 
01870    if ((sz = n * AST_MAX_FDS + nfds)) {
01871       pfds = alloca(sizeof(*pfds) * sz);
01872       fdmap = alloca(sizeof(*fdmap) * sz);
01873    }
01874 
01875    if (outfd)
01876       *outfd = -99999;
01877    if (exception)
01878       *exception = 0;
01879    
01880    /* Perform any pending masquerades */
01881    for (x=0; x < n; x++) {
01882       ast_channel_lock(c[x]);
01883       if (c[x]->masq) {
01884          if (ast_do_masquerade(c[x])) {
01885             ast_log(LOG_WARNING, "Masquerade failed\n");
01886             *ms = -1;
01887             ast_channel_unlock(c[x]);
01888             return NULL;
01889          }
01890       }
01891       if (c[x]->whentohangup) {
01892          if (!whentohangup)
01893             time(&now);
01894          diff = c[x]->whentohangup - now;
01895          if (diff < 1) {
01896             /* Should already be hungup */
01897             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
01898             ast_channel_unlock(c[x]);
01899             return c[x];
01900          }
01901          if (!whentohangup || (diff < whentohangup))
01902             whentohangup = diff;
01903       }
01904       ast_channel_unlock(c[x]);
01905    }
01906    /* Wait full interval */
01907    rms = *ms;
01908    /* INT_MAX, not LONG_MAX, because it matters on 64-bit */
01909    if (whentohangup && whentohangup < INT_MAX / 1000) { /* Protect against overflow */
01910       rms = whentohangup * 1000;              /* timeout in milliseconds */
01911       if (*ms >= 0 && *ms < rms)    /* original *ms still smaller */
01912          rms =  *ms;
01913    } else if (whentohangup && rms < 0) {
01914       /* Tiny corner case... call would need to last >24 days */
01915       rms = INT_MAX;
01916    }
01917    /*
01918     * Build the pollfd array, putting the channels' fds first,
01919     * followed by individual fds. Order is important because
01920     * individual fd's must have priority over channel fds.
01921     */
01922    max = 0;
01923    for (x=0; x<n; x++) {
01924       for (y=0; y<AST_MAX_FDS; y++) {
01925          fdmap[max].fdno = y;  /* fd y is linked to this pfds */
01926          fdmap[max].chan = x;  /* channel x is linked to this pfds */
01927          max += ast_add_fd(&pfds[max], c[x]->fds[y]);
01928       }
01929       CHECK_BLOCKING(c[x]);
01930    }
01931    /* Add the individual fds */
01932    for (x=0; x<nfds; x++) {
01933       fdmap[max].chan = -1;
01934       max += ast_add_fd(&pfds[max], fds[x]);
01935    }
01936 
01937    if (*ms > 0)
01938       start = ast_tvnow();
01939    
01940    if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */
01941       do {
01942          int kbrms = rms;
01943          if (kbrms > 600000)
01944             kbrms = 600000;
01945          res = ast_poll(pfds, max, kbrms);
01946          if (!res)
01947             rms -= kbrms;
01948       } while (!res && (rms > 0));
01949    } else {
01950       res = ast_poll(pfds, max, rms);
01951    }
01952    for (x=0; x<n; x++)
01953       ast_clear_flag(c[x], AST_FLAG_BLOCKING);
01954    if (res < 0) { /* Simulate a timeout if we were interrupted */
01955       if (errno != EINTR)
01956          *ms = -1;
01957       return NULL;
01958    }
01959    if (whentohangup) {   /* if we have a timeout, check who expired */
01960       time(&now);
01961       for (x=0; x<n; x++) {
01962          if (c[x]->whentohangup && now >= c[x]->whentohangup) {
01963             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
01964             if (winner == NULL)
01965                winner = c[x];
01966          }
01967       }
01968    }
01969    if (res == 0) { /* no fd ready, reset timeout and done */
01970       *ms = 0; /* XXX use 0 since we may not have an exact timeout. */
01971       return winner;
01972    }
01973    /*
01974     * Then check if any channel or fd has a pending event.
01975     * Remember to check channels first and fds last, as they
01976     * must have priority on setting 'winner'
01977     */
01978    for (x = 0; x < max; x++) {
01979       res = pfds[x].revents;
01980       if (res == 0)
01981          continue;
01982       if (fdmap[x].chan >= 0) {  /* this is a channel */
01983          winner = c[fdmap[x].chan]; /* override previous winners */
01984          if (res & POLLPRI)
01985             ast_set_flag(winner, AST_FLAG_EXCEPTION);
01986          else
01987             ast_clear_flag(winner, AST_FLAG_EXCEPTION);
01988          winner->fdno = fdmap[x].fdno;
01989       } else {       /* this is an fd */
01990          if (outfd)
01991             *outfd = pfds[x].fd;
01992          if (exception)
01993             *exception = (res & POLLPRI) ? -1 : 0;
01994          winner = NULL;
01995       }
01996    }
01997    if (*ms > 0) {
01998       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
01999       if (*ms < 0)
02000          *ms = 0;
02001    }
02002    return winner;
02003 }

int ast_waitfordigit ( struct ast_channel c,
int  ms 
)

Waits for a digit.

!

Parameters:
c channel to wait for a digit on
ms how many milliseconds to wait
Returns:
Returns <0 on error, 0 on no entry, and the digit on success.

Definition at line 2021 of file channel.c.

References ast_waitfordigit_full().

Referenced by _while_exec(), advanced_options(), ast_adsi_get_cpeid(), ast_adsi_get_cpeinfo(), ast_adsi_print(), ast_adsi_read_encoded_dtmf(), ast_adsi_transmit_message_full(), ast_app_dtget(), ast_control_streamfile(), ast_record_review(), builtin_atxfer(), collect_digits(), common_exec(), cpeid_exec(), dialout(), directory_exec(), forward_message(), get_folder(), ivr_dispatch(), mgcp_ss(), my_getsigstr(), pbx_builtin_waitexten(), play_mailbox_owner(), play_record_review(), read_exec(), read_newoption(), retrydial_exec(), sendnoise(), ss_thread(), testclient_exec(), testserver_exec(), vm_execmain(), vm_forwardoptions(), vm_instructions(), vm_options(), vm_tempgreeting(), wait_a_bit(), and wait_our_turn().

02022 {
02023    return ast_waitfordigit_full(c, ms, -1, -1);
02024 }

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

References ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_CONTROL_SRCCHANGE, AST_CONTROL_SRCUPDATE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_VOICE, ast_frfree, ast_log(), ast_read(), ast_set_flag, ast_test_flag, ast_waitfor_nandfds(), errno, and f.

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

02048 {
02049    /* Stop if we're a zombie or need a soft hangup */
02050    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
02051       return -1;
02052 
02053    /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */
02054    ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
02055 
02056    /* Wait for a digit, no more than ms milliseconds total. */
02057    while (ms) {
02058       struct ast_channel *rchan;
02059       int outfd;
02060 
02061       errno = 0;
02062       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
02063       if (!rchan && outfd < 0 && ms) {
02064          if (errno == 0 || errno == EINTR)
02065             continue;
02066          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
02067          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02068          return -1;
02069       } else if (outfd > -1) {
02070          /* The FD we were watching has something waiting */
02071          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02072          return 1;
02073       } else if (rchan) {
02074          int res;
02075          struct ast_frame *f = ast_read(c);
02076          if (!f)
02077             return -1;
02078 
02079          switch(f->frametype) {
02080          case AST_FRAME_DTMF_BEGIN:
02081             break;
02082          case AST_FRAME_DTMF_END:
02083             res = f->subclass;
02084             ast_frfree(f);
02085             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02086             return res;
02087          case AST_FRAME_CONTROL:
02088             switch(f->subclass) {
02089             case AST_CONTROL_HANGUP:
02090                ast_frfree(f);
02091                ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02092                return -1;
02093             case AST_CONTROL_RINGING:
02094             case AST_CONTROL_ANSWER:
02095             case AST_CONTROL_SRCUPDATE:
02096             case AST_CONTROL_SRCCHANGE:
02097                /* Unimportant */
02098                break;
02099             default:
02100                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
02101                break;
02102             }
02103             break;
02104          case AST_FRAME_VOICE:
02105             /* Write audio if appropriate */
02106             if (audiofd > -1) {
02107                if (write(audiofd, f->data, f->datalen) < 0) {
02108                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
02109                }
02110             }
02111          default:
02112             /* Ignore */
02113             break;
02114          }
02115          ast_frfree(f);
02116       }
02117    }
02118 
02119    ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02120 
02121    return 0; /* Time is up */
02122 }

struct ast_channel* ast_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.

Definition at line 1235 of file channel.c.

References channel_find_locked().

Referenced by next_channel().

01237 {
01238    return channel_find_locked(chan, NULL, 0, context, exten);
01239 }

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

Get channel by name prefix (locks channel).

Definition at line 1222 of file channel.c.

References channel_find_locked().

Referenced by next_channel().

01224 {
01225    return channel_find_locked(chan, name, namelen, NULL, NULL);
01226 }

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

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

Referenced by adsi_careful_send(), agent_write(), ast_bridge_call(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_udptl_bridge(), ast_write_video(), bridge_native_loop(), conf_queue_dtmf(), conf_run(), dahdi_bridge(), dictate_exec(), echo_exec(), feature_request_and_dial(), features_write(), function_ilink(), gen_generate(), handle_link_data(), jb_get_and_deliver(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), NBScat_exec(), rpt(), send_link_dtmf(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), spy_generate(), and wait_for_answer().

03131 {
03132    int res = -1;
03133    int count = 0;
03134    struct ast_frame *f = NULL;
03135 
03136    /*Deadlock avoidance*/
03137    while(ast_channel_trylock(chan)) {
03138       /*cannot goto done since the channel is not locked*/
03139       if(count++ > 10) {
03140          if(option_debug)
03141             ast_log(LOG_DEBUG, "Deadlock avoided for write to channel '%s'\n", chan->name);
03142          return 0;
03143       }
03144       usleep(1);
03145    }
03146    /* Stop if we're a zombie or need a soft hangup */
03147    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
03148       goto done;
03149 
03150    /* Handle any pending masquerades */
03151    if (chan->masq && ast_do_masquerade(chan)) {
03152       ast_log(LOG_WARNING, "Failed to perform masquerade\n");
03153       goto done;
03154    }
03155    if (chan->masqr) {
03156       res = 0; /* XXX explain, why 0 ? */
03157       goto done;
03158    }
03159    if (chan->generatordata && (!fr->src || strcasecmp(fr->src, "ast_prod"))) {
03160       if (ast_test_flag(chan, AST_FLAG_WRITE_INT)) {
03161             ast_deactivate_generator(chan);
03162       } else {
03163          if (fr->frametype == AST_FRAME_DTMF_END) {
03164             /* There is a generator running while we're in the middle of a digit.
03165              * It's probably inband DTMF, so go ahead and pass it so it can
03166              * stop the generator */
03167             ast_clear_flag(chan, AST_FLAG_BLOCKING);
03168             ast_channel_unlock(chan);
03169             res = ast_senddigit_end(chan, fr->subclass, fr->len);
03170             ast_channel_lock(chan);
03171             CHECK_BLOCKING(chan);
03172          } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass == AST_CONTROL_UNHOLD) {
03173             /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */
03174             res = (chan->tech->indicate == NULL) ? 0 :
03175                chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
03176          }
03177          res = 0; /* XXX explain, why 0 ? */
03178          goto done;
03179       }
03180    }
03181    /* High bit prints debugging */
03182    if (chan->fout & DEBUGCHAN_FLAG)
03183       ast_frame_dump(chan->name, fr, ">>");
03184    CHECK_BLOCKING(chan);
03185    switch(fr->frametype) {
03186    case AST_FRAME_CONTROL:
03187       res = (chan->tech->indicate == NULL) ? 0 :
03188          chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
03189       break;
03190    case AST_FRAME_DTMF_BEGIN:
03191       if (chan->audiohooks) {
03192          struct ast_frame *old_frame = fr;
03193          fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
03194          if (old_frame != fr)
03195             f = fr;
03196       }
03197       ast_clear_flag(chan, AST_FLAG_BLOCKING);
03198       ast_channel_unlock(chan);
03199       res = ast_senddigit_begin(chan, fr->subclass);
03200       ast_channel_lock(chan);
03201       CHECK_BLOCKING(chan);
03202       break;
03203    case AST_FRAME_DTMF_END:
03204       if (chan->audiohooks) {
03205          struct ast_frame *new_frame = fr;
03206 
03207          new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
03208          if (new_frame != fr) {
03209             ast_frfree(new_frame);
03210          }
03211       }
03212       ast_clear_flag(chan, AST_FLAG_BLOCKING);
03213       ast_channel_unlock(chan);
03214       res = ast_senddigit_end(chan, fr->subclass, fr->len);
03215       ast_channel_lock(chan);
03216       CHECK_BLOCKING(chan);
03217       break;
03218    case AST_FRAME_TEXT:
03219       res = (chan->tech->send_text == NULL) ? 0 :
03220          chan->tech->send_text(chan, (char *) fr->data);
03221       break;
03222    case AST_FRAME_HTML:
03223       res = (chan->tech->send_html == NULL) ? 0 :
03224          chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
03225       break;
03226    case AST_FRAME_VIDEO:
03227       /* XXX Handle translation of video codecs one day XXX */
03228       res = (chan->tech->write_video == NULL) ? 0 :
03229          chan->tech->write_video(chan, fr);
03230       break;
03231    case AST_FRAME_MODEM:
03232       res = (chan->tech->write == NULL) ? 0 :
03233          chan->tech->write(chan, fr);
03234       break;
03235    case AST_FRAME_VOICE:
03236       if (chan->tech->write == NULL)
03237          break;   /*! \todo XXX should return 0 maybe ? */
03238 
03239       if (ast_opt_generic_plc && fr->subclass == AST_FORMAT_SLINEAR) {
03240          apply_plc(chan, fr);
03241       }
03242 
03243       /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
03244       if (fr->subclass == chan->rawwriteformat)
03245          f = fr;
03246       else
03247          f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
03248 
03249       /* If we have no frame of audio, then we have to bail out */
03250       if (!f) {
03251          res = 0;
03252          break;
03253       }
03254 
03255       if (chan->audiohooks) {
03256          struct ast_frame *prev = NULL, *new_frame, *cur, *dup;
03257          int freeoldlist = 0;
03258 
03259          if (f != fr) {
03260             freeoldlist = 1;
03261          }
03262 
03263          /* Since ast_audiohook_write may return a new frame, and the cur frame is
03264           * an item in a list of frames, create a new list adding each cur frame back to it
03265           * regardless if the cur frame changes or not. */
03266          for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
03267             new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur);
03268 
03269             /* if this frame is different than cur, preserve the end of the list,
03270              * free the old frames, and set cur to be the new frame */
03271             if (new_frame != cur) {
03272 
03273                /* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame
03274                 * isn't part of local storage, meaning if ast_audiohook_write is called multiple
03275                 * times it may override the previous frame we got from it unless we dup it */
03276                if ((dup = ast_frisolate(new_frame))) {
03277                   AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list);
03278                   if (freeoldlist) {
03279                      AST_LIST_NEXT(cur, frame_list) = NULL;
03280                      ast_frfree(cur);
03281                   }
03282                   if (new_frame != dup) {
03283                      ast_frfree(new_frame);
03284                   }
03285                   cur = dup;
03286                }
03287             }
03288 
03289             /* now, regardless if cur is new or not, add it to the new list,
03290              * if the new list has not started, cur will become the first item. */
03291             if (prev) {
03292                AST_LIST_NEXT(prev, frame_list) = cur;
03293             } else {
03294                f = cur; /* set f to be the beginning of our new list */
03295             }
03296             prev = cur;
03297          }
03298       }
03299       
03300       /* If Monitor is running on this channel, then we have to write frames out there too */
03301       /* the translator on chan->writetrans may have returned multiple frames
03302          from the single frame we passed in; if so, feed each one of them to the
03303          monitor */
03304       if (chan->monitor && chan->monitor->write_stream) {
03305          struct ast_frame *cur;
03306 
03307          for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
03308          /* XXX must explain this code */
03309 #ifndef MONITOR_CONSTANT_DELAY
03310             int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples;
03311             if (jump >= 0) {
03312                jump = chan->insmpl - chan->outsmpl;
03313                if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
03314                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
03315                chan->outsmpl += jump + cur->samples;
03316             } else {
03317                chan->outsmpl += cur->samples;
03318             }
03319 #else
03320             int jump = chan->insmpl - chan->outsmpl;
03321             if (jump - MONITOR_DELAY >= 0) {
03322                if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1)
03323                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
03324                chan->outsmpl += jump;
03325             } else {
03326                chan->outsmpl += cur->samples;
03327             }
03328 #endif
03329             if (chan->monitor->state == AST_MONITOR_RUNNING) {
03330                if (ast_writestream(chan->monitor->write_stream, cur) < 0)
03331                   ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
03332             }
03333          }
03334       }
03335 
03336       /* the translator on chan->writetrans may have returned multiple frames
03337          from the single frame we passed in; if so, feed each one of them to the
03338          channel, freeing each one after it has been written */
03339       if ((f != fr) && AST_LIST_NEXT(f, frame_list)) {
03340          struct ast_frame *cur, *next;
03341          unsigned int skip = 0;
03342 
03343          for (cur = f, next = AST_LIST_NEXT(cur, frame_list);
03344               cur;
03345               cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) {
03346             if (!skip) {
03347                if ((res = chan->tech->write(chan, cur)) < 0) {
03348                   chan->_softhangup |= AST_SOFTHANGUP_DEV;
03349                   skip = 1;
03350                } else if (next) {
03351                   /* don't do this for the last frame in the list,
03352                      as the code outside the loop will do it once
03353                   */
03354                   chan->fout = FRAMECOUNT_INC(chan->fout);
03355                }
03356             }
03357             ast_frfree(cur);
03358          }
03359 
03360          /* reset f so the code below doesn't attempt to free it */
03361          f = NULL;
03362       } else {
03363          res = chan->tech->write(chan, f);
03364       }
03365       break;
03366    case AST_FRAME_NULL:
03367    case AST_FRAME_IAX:
03368       /* Ignore these */
03369       res = 0;
03370       break;
03371    default:
03372       /* At this point, fr is the incoming frame and f is NULL.  Channels do
03373        * not expect to get NULL as a frame pointer and will segfault.  Hence,
03374        * we output the original frame passed in. */
03375       res = chan->tech->write(chan, fr);
03376       break;
03377    }
03378 
03379    if (f && f != fr)
03380       ast_frfree(f);
03381    ast_clear_flag(chan, AST_FLAG_BLOCKING);
03382 
03383    /* Consider a write failure to force a soft hangup */
03384    if (res < 0) {
03385       chan->_softhangup |= AST_SOFTHANGUP_DEV;
03386    } else {
03387       chan->fout = FRAMECOUNT_INC(chan->fout);
03388    }
03389 done:
03390    if (chan->audiohooks && ast_audiohook_write_list_empty(chan->audiohooks)) {
03391       /* The list gets recreated if audiohooks are added again later */
03392       ast_audiohook_detach_list(chan->audiohooks);
03393       chan->audiohooks = NULL;
03394    }
03395    ast_channel_unlock(chan);
03396    return res;
03397 }

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

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

03016 {
03017    int res;
03018    if (!chan->tech->write_video)
03019       return 0;
03020    res = ast_write(chan, fr);
03021    if (!res)
03022       res = 1;
03023    return res;
03024 }

const char* channelreloadreason2txt ( enum channelreloadreason  reason  ) 

Convert enum channelreloadreason to text string for manager event.

\ brief Convert channel reloadreason (ENUM) to text string for manager event

Definition at line 5415 of file channel.c.

References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.

05416 {
05417    switch (reason) {
05418    case CHANNEL_MODULE_LOAD:
05419       return "LOAD (Channel module load)";
05420 
05421    case CHANNEL_MODULE_RELOAD:
05422       return "RELOAD (Channel module reload)";
05423 
05424    case CHANNEL_CLI_RELOAD:
05425       return "CLIRELOAD (Channel module reload by CLI command)";
05426 
05427    default:
05428       return "MANAGERRELOAD (Channel module reload by manager)";
05429    }
05430 };


Generated on Sat Aug 6 00:39:54 2011 for Asterisk - the Open Source PBX by  doxygen 1.4.7