Fri Sep 25 19:28:32 2009

Asterisk developer's documentation


channel.c File Reference

Channel Management. More...

#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <math.h>
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
#include "asterisk/sched.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/chanspy.h"
#include "asterisk/musiconhold.h"
#include "asterisk/logger.h"
#include "asterisk/say.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/manager.h"
#include "asterisk/chanvars.h"
#include "asterisk/linkedlists.h"
#include "asterisk/indications.h"
#include "asterisk/monitor.h"
#include "asterisk/causes.h"
#include "asterisk/callerid.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/transcap.h"
#include "asterisk/devicestate.h"
#include "asterisk/sha1.h"
#include "asterisk/threadstorage.h"
#include "asterisk/slinfactory.h"

Include dependency graph for channel.c:

Go to the source code of this file.

Data Structures

struct  ast_cause
struct  ast_channel_spy_list
struct  ast_channel_whisper_buffer
struct  ast_silence_generator
struct  chanlist
struct  channel_spy_trans
struct  tonepair_def
struct  tonepair_state

Defines

#define AST_DEFAULT_EMULATE_DTMF_DURATION   100
#define AST_MIN_DTMF_DURATION   80
#define AST_MIN_DTMF_GAP   45
#define FORMAT   "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n"
#define SPY_QUEUE_SAMPLE_LIMIT   4000
#define STATE2STR_BUFSIZE   32

Enumerations

enum  spy_direction { SPY_READ, SPY_WRITE }

Functions

static struct ast_frame__ast_read (struct ast_channel *chan, int dropaudio)
struct ast_channel__ast_request_and_dial (const char *type, int format, void *data, int timeout, int *outstate, int callingpres, const char *cid_num, const char *cid_name, struct outgoing_helper *oh, char *uniqueid)
int ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params)
int ast_active_channels (void)
 returns number of active/allocated channels
char * ast_alloc_uniqueid (void)
 Create a uniqueid.
int ast_answer (struct ast_channel *chan)
 Answer a ringing call.
void ast_begin_shutdown (int hangup)
 Initiate system shutdown.
int ast_best_codec (int fmts)
 Pick the best audio codec.
struct ast_channelast_bridged_channel (struct ast_channel *chan)
 Find bridged channel.
int ast_call (struct ast_channel *chan, char *addr, int timeout)
 Make a call.
void ast_cancel_shutdown (void)
 Cancel a shutdown in progress.
const char * ast_cause2str (int cause)
 Gives the string form of a given hangup cause.
void ast_change_name (struct ast_channel *chan, char *newname)
 Change channel name.
struct ast_channelast_channel_alloc (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *name_fmt,...)
 Create a new channel structure.
enum ast_bridge_result ast_channel_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
 Bridge two channels together.
int ast_channel_cmpwhentohangup (struct ast_channel *chan, time_t offset)
 Compare a offset with when to hangup channel.
int ast_channel_datastore_add (struct ast_channel *chan, struct ast_datastore *datastore)
 Add a datastore to a channel.
struct ast_datastoreast_channel_datastore_alloc (const struct ast_datastore_info *info, char *uid)
 Create a channel datastore structure.
struct ast_datastoreast_channel_datastore_find (struct ast_channel *chan, const struct ast_datastore_info *info, char *uid)
 Find a datastore on a channel.
int ast_channel_datastore_free (struct ast_datastore *datastore)
 Free a channel datastore structure.
int ast_channel_datastore_inherit (struct ast_channel *from, struct ast_channel *to)
 Inherit datastores from a parent to a child.
int ast_channel_datastore_remove (struct ast_channel *chan, struct ast_datastore *datastore)
 Remove a datastore from a channel.
int ast_channel_defer_dtmf (struct ast_channel *chan)
 Set defer DTMF flag on channel.
void ast_channel_free (struct ast_channel *chan)
 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 *chan, struct ast_channel *peer)
 Makes two channel formats compatible.
int ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone)
 Weird function made for call transfers.
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 new telephony channel in Asterisk.
int ast_channel_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen)
int ast_channel_sendurl (struct ast_channel *chan, const char *url)
int ast_channel_setoption (struct ast_channel *chan, 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 hangup channel.
int ast_channel_spy_add (struct ast_channel *chan, struct ast_channel_spy *spy)
 Adds a spy to a channel, to begin receiving copies of the channel's audio frames.
void ast_channel_spy_free (struct ast_channel_spy *spy)
 Free a spy.
struct ast_frameast_channel_spy_read_frame (struct ast_channel_spy *spy, unsigned int samples)
 Read one (or more) frames of audio from a channel being spied upon.
void ast_channel_spy_remove (struct ast_channel *chan, struct ast_channel_spy *spy)
 Remove a spy from a channel.
void ast_channel_spy_stop_by_type (struct ast_channel *chan, const char *type)
 Find all spies of a particular type on a channel and stop them.
void ast_channel_spy_trigger_wait (struct ast_channel_spy *spy)
 Efficiently wait until audio is available for a spy, or an exception occurs.
struct ast_silence_generatorast_channel_start_silence_generator (struct ast_channel *chan)
 Starts a silence generator on the given channel.
void ast_channel_stop_silence_generator (struct ast_channel *chan, struct ast_silence_generator *state)
 Stops a previously-started silence generator on the given channel.
int ast_channel_supports_html (struct ast_channel *chan)
void ast_channel_undefer_dtmf (struct ast_channel *chan)
 Unset defer DTMF flag on channel.
void ast_channel_unregister (const struct ast_channel_tech *tech)
 Unregister a channel technology.
struct ast_channelast_channel_walk_locked (const struct ast_channel *prev)
 Browse channels in use.
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.
void ast_channels_init (void)
struct ast_variableast_channeltype_list (void)
 return an ast_variable list of channeltypes
int ast_check_hangup (struct ast_channel *chan)
 Checks to see if a channel is needing hang up.
static int ast_check_hangup_locked (struct ast_channel *chan)
void ast_deactivate_generator (struct ast_channel *chan)
int ast_do_masquerade (struct ast_channel *original)
 Masquerade a channel.
static enum ast_bridge_result ast_generic_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc, struct timeval bridge_end)
struct ast_channelast_get_channel_by_exten_locked (const char *exten, const char *context)
 Get channel by exten (and optionally context) and lock it.
struct ast_channelast_get_channel_by_name_locked (const char *name)
 Get channel by name and lock it.
struct ast_channelast_get_channel_by_name_prefix_locked (const char *name, const int namelen)
 Get channel by name prefix and lock it.
struct ast_channelast_get_channel_by_uniqueid_locked (const char *uniqueid)
struct ast_channel_techast_get_channel_tech (const char *name)
 Get a channel technology structure by name.
ast_group_t ast_get_group (const char *s)
int ast_hangup (struct ast_channel *chan)
 Hangup 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.
void ast_install_music_functions (int(*start_ptr)(struct ast_channel *, const char *, const char *), void(*stop_ptr)(struct ast_channel *), void(*cleanup_ptr)(struct ast_channel *))
int ast_internal_timing_enabled (struct ast_channel *chan)
 Check if the channel can run in internal timing mode.
static AST_LIST_HEAD_NOLOCK_STATIC (backends, chanlist)
static AST_LIST_HEAD_STATIC (channels, ast_channel)
void ast_moh_cleanup (struct ast_channel *chan)
int ast_moh_start (struct ast_channel *chan, const char *mclass, const char *interpclass)
 Turn on music on hold on a given channel.
void ast_moh_stop (struct ast_channel *chan)
 Turn off music on hold on a given channel.
char * ast_print_group (char *buf, int buflen, ast_group_t group)
 Print call group and pickup group ---.
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.
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 *fin)
 Queue an outgoing media frame.
int ast_queue_hangup (struct ast_channel *chan)
 Queue a hangup frame for channel.
struct ast_frameast_read (struct ast_channel *chan)
 Reads a frame.
static void ast_read_generator_actions (struct ast_channel *chan, struct ast_frame *f)
struct ast_frameast_read_noaudio (struct ast_channel *chan)
 Reads a frame, returning AST_FRAME_NULL frame if audio. Read a frame.
int ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
int ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
int ast_recvchar (struct ast_channel *chan, int timeout)
 Receives a text character from a channel.
char * ast_recvtext (struct ast_channel *chan, int timeout)
 Receives a text string from a channel Read a string of text from a channel.
struct ast_channelast_request (const char *type, int format, void *data, int *cause)
 Requests a channel.
struct ast_channelast_request_and_dial (const char *type, int format, void *data, int timeout, int *outstate, int callingpres, const char *cidnum, const char *cidname, char *uniqueid)
 Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
struct ast_channelast_request_with_uniqueid (const char *type, int format, void *data, int *cause, char *uniqueid)
 Requests a channel.
int ast_safe_sleep (struct ast_channel *chan, int ms)
 Wait, look for hangups.
int ast_safe_sleep_conditional (struct ast_channel *chan, int ms, int(*cond)(void *), void *data)
 Wait, look for hangups and condition arg.
char * ast_safe_string_alloc (const char *fmt,...)
 printf the string into a correctly sized mallocd buffer, and return the buffer
int ast_say_character_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang)
int ast_say_digit_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang)
int ast_say_digits (struct ast_channel *chan, int num, const char *ints, const char *lang)
int ast_say_digits_full (struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
int ast_say_enumeration (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options)
int ast_say_number (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options)
int ast_say_phonetic_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang)
int ast_send_message (const char *type, void *data, char *to, char *from, char *message, int ispdu)
 "Requests" a channel for sending a message
int ast_senddigit (struct ast_channel *chan, char digit)
 Send a DTMF digit to a channel Send a DTMF digit to a channel.
int ast_senddigit_begin (struct ast_channel *chan, char digit)
int ast_senddigit_end (struct ast_channel *chan, char digit, unsigned int duration)
int ast_sendtext (struct ast_channel *chan, const char *dest, const char *text, int ispdu)
 Sends text to a channel Write text to a display on a channel.
void ast_set_callerid (struct ast_channel *chan, const char *callerid, const char *calleridname, const char *ani)
int ast_set_read_format (struct ast_channel *chan, int fmt)
 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 fmt)
 Sets write format on channel chan Set write format for channel to whichever compoent of "format" is best.
int ast_setstate (struct ast_channel *chan, enum ast_channel_state state)
 Change the state of a channel.
int ast_setstate_and_cid (struct ast_channel *chan, enum ast_channel_state state, char *cid_num, char *cid_name)
 Change the state of a channel and the callerid of the calling channel.
int ast_settimeout (struct ast_channel *c, int samples, int(*func)(const void *data), void *data)
int ast_shutting_down (void)
 Returns non-zero if Asterisk is being shut down.
int ast_softhangup (struct ast_channel *chan, int cause)
 Softly hangup a channel, lock.
int ast_softhangup_nolock (struct ast_channel *chan, int cause)
 Softly hangup a channel, don't lock.
char * ast_state2str (enum ast_channel_state state)
 Gives the string form of a given channel state.
int ast_str2cause (const char *name)
 Convert a symbolic hangup cause to number.
 AST_THREADSTORAGE (state2str_threadbuf, state2str_threadbuf_init)
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 call to dest, if the channel supports transfer.
char * ast_transfercapability2str (int transfercapability)
 Gives the string form of a given transfer capability.
void ast_uninstall_music_functions (void)
int ast_waitfor (struct ast_channel *c, int ms)
 Wait for input on a channel.
struct ast_channelast_waitfor_n (struct ast_channel **c, 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)
 Wait for x amount of time on a file descriptor to have input.
struct ast_channelast_waitfor_nandfds (struct ast_channel **c, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
 Wait for x amount of time on a file descriptor to have input.
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 cmdfd)
 Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
struct ast_channelast_walk_channel_by_exten_locked (const struct ast_channel *chan, const char *exten, const char *context)
 Get next channel by exten (and optionally context) and lock it.
struct ast_channelast_walk_channel_by_name_prefix_locked (const struct ast_channel *chan, const char *name, const int namelen)
 Get next channel by name prefix and lock it.
int ast_write (struct ast_channel *chan, struct ast_frame *fr)
 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 *fr)
 Write video frame to a channel This function writes the given frame to the indicated channel.
static void bridge_playfile (struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
static struct ast_channelchannel_find_locked (const struct ast_channel *prev, const char *name, const int namelen, const char *context, const char *exten, const char *uniqueid)
 Helper function to find channels.
const char * channelreloadreason2txt (enum channelreloadreason reason)
 Convert enum channelreloadreason to text string for manager event.
static void clone_variables (struct ast_channel *original, struct ast_channel *clone)
 Clone channel variables from 'clone' channel into 'original' channel.
static char * complete_channeltypes (const char *line, const char *word, int pos, int state)
static char * complete_channeltypes_deprecated (const char *line, const char *word, int pos, int state)
static void copy_data_from_queue (struct ast_channel_spy_queue *queue, short *buf, unsigned int samples)
static void detach_spies (struct ast_channel *chan)
static void free_cid (struct ast_callerid *cid)
static void free_translation (struct ast_channel *clone)
static int generator_force (const void *data)
static void queue_frame_to_spies (struct ast_channel *chan, struct ast_frame *f, enum spy_direction dir)
static int set_format (struct ast_channel *chan, int fmt, int *rawformat, int *format, struct ast_trans_pvt **trans, const int direction)
static int show_channeltype (int fd, int argc, char *argv[])
static int show_channeltype_deprecated (int fd, int argc, char *argv[])
static int show_channeltypes (int fd, int argc, char *argv[])
static void * silence_generator_alloc (struct ast_channel *chan, void *data)
static int silence_generator_generate (struct ast_channel *chan, void *data, int len, int samples)
static void silence_generator_release (struct ast_channel *chan, void *data)
static void spy_cleanup (struct ast_channel *chan)
static void spy_detach (struct ast_channel_spy *spy, struct ast_channel *chan)
static void * tonepair_alloc (struct ast_channel *chan, void *params)
static int tonepair_generator (struct ast_channel *chan, void *data, int len, int samples)
static void tonepair_release (struct ast_channel *chan, void *params)

Variables

static void(* ast_moh_cleanup_ptr )(struct ast_channel *) = NULL
static int(* ast_moh_start_ptr )(struct ast_channel *, const char *, const char *) = NULL
static void(* ast_moh_stop_ptr )(struct ast_channel *) = NULL
struct ast_cause causes []
static struct ast_cli_entry cli_channel []
static struct ast_cli_entry cli_show_channeltype_deprecated
static struct ast_cli_entry cli_show_channeltypes_deprecated
unsigned long global_fin
unsigned long global_fout
static struct ast_channel_tech null_tech
static char show_channeltype_usage []
static char show_channeltypes_usage []
static int shutting_down
static struct ast_generator silence_generator
static struct ast_generator tonepair
static int uniqueint


Detailed Description

Channel Management.

Author:
Mark Spencer <markster@digium.com>

Definition in file channel.c.


Define Documentation

#define AST_DEFAULT_EMULATE_DTMF_DURATION   100

Default amount of time to use when emulating a digit as a begin and end 100ms

Definition at line 109 of file channel.c.

Referenced by __ast_read(), and ast_senddigit().

#define AST_MIN_DTMF_DURATION   80

Minimum allowed digit length - 80ms

Definition at line 112 of file channel.c.

Referenced by __ast_read().

#define AST_MIN_DTMF_GAP   45

Minimum amount of time between the end of the last digit and the beginning of a new one - 45ms

Definition at line 116 of file channel.c.

Referenced by __ast_read().

#define FORMAT   "%-10.10s %-40.40s %-12.12s %-12.12s %-12.12s\n"

#define SPY_QUEUE_SAMPLE_LIMIT   4000

Definition at line 1614 of file channel.c.

Referenced by queue_frame_to_spies().

#define STATE2STR_BUFSIZE   32

Definition at line 105 of file channel.c.

Referenced by ast_state2str().


Enumeration Type Documentation

Enumerator:
SPY_READ 
SPY_WRITE 

Definition at line 1609 of file channel.c.

01609                    {
01610    SPY_READ,
01611    SPY_WRITE,
01612 };


Function Documentation

static struct ast_frame* __ast_read ( struct ast_channel chan,
int  dropaudio 
) [static, read]

Definition at line 2228 of file channel.c.

References ast_channel::_softhangup, ast_channel::_state, ast_channel::alertpipe, ast_cdr_alloc(), ast_cdr_answer(), ast_cdr_end(), ast_cdr_init(), ast_cdr_start(), ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, ast_deactivate_generator(), AST_DEFAULT_EMULATE_DTMF_DURATION, ast_do_masquerade(), AST_FLAG_DEFER_DTMF, AST_FLAG_EMULATE_DTMF, AST_FLAG_END_DTMF_ONLY, AST_FLAG_EXCEPTION, AST_FLAG_IN_DTMF, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree, AST_GENERATOR_FD, ast_getformatname(), AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_NEXT, AST_LIST_REMOVE_HEAD, ast_log(), AST_MIN_DTMF_DURATION, AST_MIN_DTMF_GAP, AST_MONITOR_RUNNING, ast_null_frame, ast_read_generator_actions(), ast_seekstream(), ast_set_flag, ast_setstate(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, AST_TIMING_FD, ast_translate(), ast_writestream(), ast_channel::blocker, ast_channel::cdr, DEBUGCHAN_FLAG, ast_channel::dtmf_tv, ast_channel::dtmff, ast_channel::dtmfq, ast_channel::emulate_dtmf_digit, ast_channel::emulate_dtmf_duration, errno, ast_channel_tech::exception, f, ast_channel::fdno, ast_channel::fds, ast_channel::fin, FRAMECOUNT_INC, ast_frame::frametype, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, ast_channel::insmpl, ast_frame::len, LOG_DEBUG, LOG_DTMF, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::nativeformats, option_debug, ast_channel::outsmpl, queue_frame_to_spies(), ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readtrans, ast_frame::samples, SEEK_FORCECUR, ast_channel::spies, SPY_READ, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.

Referenced by ast_read(), and ast_read_noaudio().

02229 {
02230    struct ast_frame *f = NULL;   /* the return value */
02231    int blah;
02232    int prestate;
02233    int count = 0;
02234 
02235    /* this function is very long so make sure there is only one return
02236     * point at the end (there are only two exceptions to this).
02237     */
02238    while(ast_channel_trylock(chan)) {
02239       if(count++ > 10) 
02240          /*cannot goto done since the channel is not locked*/
02241          return &ast_null_frame;
02242       usleep(1);
02243    }
02244 
02245    if (chan->masq) {
02246       if (ast_do_masquerade(chan))
02247          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02248       else
02249          f =  &ast_null_frame;
02250       goto done;
02251    }
02252 
02253    /* Stop if we're a zombie or need a soft hangup */
02254    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02255       if (chan->generator)
02256          ast_deactivate_generator(chan);
02257       goto done;
02258    }
02259    prestate = chan->_state;
02260 
02261    if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF | AST_FLAG_IN_DTMF) && 
02262        !ast_strlen_zero(chan->dtmfq) && 
02263       (ast_tvzero(chan->dtmf_tv) || ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) > AST_MIN_DTMF_GAP) ) {
02264       /* We have DTMF that has been deferred.  Return it now */
02265       chan->dtmff.subclass = chan->dtmfq[0];
02266       /* Drop first digit from the buffer */
02267       memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
02268       f = &chan->dtmff;
02269       if (ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
02270          ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
02271          chan->dtmff.frametype = AST_FRAME_DTMF_END;
02272       } else {
02273          ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %d queued on %s\n", f->subclass, AST_DEFAULT_EMULATE_DTMF_DURATION, chan->name);
02274          chan->dtmff.frametype = AST_FRAME_DTMF_BEGIN;
02275          ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02276          chan->emulate_dtmf_digit = f->subclass;
02277          chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
02278       }
02279       chan->dtmf_tv = ast_tvnow();
02280       goto done;
02281    }
02282    
02283    /* Read and ignore anything on the alertpipe, but read only
02284       one sizeof(blah) per frame that we send from it */
02285    if (chan->alertpipe[0] > -1)
02286       read(chan->alertpipe[0], &blah, sizeof(blah));
02287 
02288 #ifdef HAVE_ZAPTEL
02289    if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02290       int res;
02291 
02292       ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02293       blah = -1;
02294       /* IF we can't get event, assume it's an expired as-per the old interface */
02295       res = ioctl(chan->timingfd, ZT_GETEVENT, &blah);
02296       if (res)
02297          blah = ZT_EVENT_TIMER_EXPIRED;
02298 
02299       if (blah == ZT_EVENT_TIMER_PING) {
02300          if (AST_LIST_EMPTY(&chan->readq) || !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
02301             /* Acknowledge PONG unless we need it again */
02302             if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) {
02303                ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
02304             }
02305          }
02306       } else if (blah == ZT_EVENT_TIMER_EXPIRED) {
02307          ioctl(chan->timingfd, ZT_TIMERACK, &blah);
02308          if (chan->timingfunc) {
02309             chan->timingfunc(chan->timingdata);
02310          } else {
02311             blah = 0;
02312             ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
02313             chan->timingdata = NULL;
02314          }
02315          ast_channel_unlock(chan);
02316          /* cannot 'goto done' because the channel is already unlocked */
02317          return &ast_null_frame;
02318       } else
02319          ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
02320    } else
02321 #endif
02322    if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
02323       /* if the AST_GENERATOR_FD is set, call the generator with args
02324        * set to -1 so it can do whatever it needs to.
02325        */
02326       void *tmp = chan->generatordata;
02327       chan->generatordata = NULL;     /* reset to let ast_write get through */
02328       chan->generator->generate(chan, tmp, -1, -1);
02329       chan->generatordata = tmp;
02330       f = &ast_null_frame;
02331       goto done;
02332    }
02333 
02334    /* Check for pending read queue */
02335    if (!AST_LIST_EMPTY(&chan->readq)) {
02336       f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list);
02337       /* Interpret hangup and return NULL */
02338       /* XXX why not the same for frames from the channel ? */
02339       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
02340          ast_frfree(f);
02341          f = NULL;
02342       }
02343    } else {
02344       chan->blocker = pthread_self();
02345       if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02346          if (chan->tech->exception)
02347             f = chan->tech->exception(chan);
02348          else {
02349             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
02350             f = &ast_null_frame;
02351          }
02352          /* Clear the exception flag */
02353          ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02354       } else if (chan->tech->read)
02355          f = chan->tech->read(chan);
02356       else
02357          ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
02358    }
02359 
02360    if (f) {
02361       /* if the channel driver returned more than one frame, stuff the excess
02362          into the readq for the next ast_read call (note that we can safely assume
02363          that the readq is empty, because otherwise we would not have called into
02364          the channel driver and f would be only a single frame)
02365       */
02366       if (AST_LIST_NEXT(f, frame_list)) {
02367          AST_LIST_HEAD_SET_NOLOCK(&chan->readq, AST_LIST_NEXT(f, frame_list));
02368          AST_LIST_NEXT(f, frame_list) = NULL;
02369       }
02370 
02371       switch (f->frametype) {
02372       case AST_FRAME_CONTROL:
02373          if (f->subclass == AST_CONTROL_ANSWER) {
02374             if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02375                if (option_debug)
02376                   ast_log(LOG_DEBUG, "Ignoring answer on an inbound call!\n");
02377                ast_frfree(f);
02378                f = &ast_null_frame;
02379             } else if (prestate == AST_STATE_UP) {
02380                if (option_debug)
02381                   ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
02382                ast_frfree(f);
02383                f = &ast_null_frame;
02384             } else {
02385                /* Answer the CDR */
02386                ast_setstate(chan, AST_STATE_UP);
02387                if (!chan->cdr) { /* up till now, this insertion hasn't been done. Therefore,
02388                                to keep from throwing off the basic order of the universe,
02389                                we will try to keep this cdr from getting posted. */
02390                   chan->cdr = ast_cdr_alloc();
02391                   ast_cdr_init(chan->cdr, chan);
02392                   ast_cdr_start(chan->cdr);
02393                }
02394                
02395                ast_cdr_answer(chan->cdr);
02396             }
02397          }
02398          break;
02399       case AST_FRAME_DTMF_END:
02400          ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass, chan->name, f->len);
02401          /* Queue it up if DTMF is deffered, or if DTMF emulation is forced.
02402           * However, only let emulation be forced if the other end cares about BEGIN frames */
02403          if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF) ||
02404             (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) ) {
02405             if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) {
02406                ast_log(LOG_DTMF, "DTMF end '%c' put into dtmf queue on %s\n", f->subclass, chan->name);
02407                chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
02408             } else
02409                ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
02410             ast_frfree(f);
02411             f = &ast_null_frame;
02412          } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
02413             if (!ast_tvzero(chan->dtmf_tv) && 
02414                 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
02415                /* If it hasn't been long enough, defer this digit */
02416                if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) {
02417                   ast_log(LOG_DTMF, "DTMF end '%c' put into dtmf queue on %s\n", f->subclass, chan->name);
02418                   chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
02419                } else
02420                   ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
02421                ast_frfree(f);
02422                f = &ast_null_frame;
02423             } else {
02424                /* There was no begin, turn this into a begin and send the end later */
02425                f->frametype = AST_FRAME_DTMF_BEGIN;
02426                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02427                chan->emulate_dtmf_digit = f->subclass;
02428                chan->dtmf_tv = ast_tvnow();
02429                if (f->len) {
02430                   if (f->len > AST_MIN_DTMF_DURATION)
02431                      chan->emulate_dtmf_duration = f->len;
02432                   else 
02433                      chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
02434                } else
02435                   chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
02436                ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass, chan->emulate_dtmf_duration, chan->name);
02437             }
02438          } else {
02439             struct timeval now = ast_tvnow();
02440             if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02441                ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass, chan->name);
02442                ast_clear_flag(chan, AST_FLAG_IN_DTMF);
02443                if (!f->len)
02444                   f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02445             } else if (!f->len) {
02446                ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass, chan->name);
02447                f->len = AST_MIN_DTMF_DURATION;
02448             }
02449             if (f->len < AST_MIN_DTMF_DURATION) {
02450                ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass, f->len, AST_MIN_DTMF_DURATION, chan->name);
02451                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02452                chan->emulate_dtmf_digit = f->subclass;
02453                chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
02454                ast_frfree(f);
02455                f = &ast_null_frame;
02456             } else {
02457                ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass, chan->name);
02458                chan->dtmf_tv = now;
02459             }
02460          }
02461          break;
02462       case AST_FRAME_DTMF_BEGIN:
02463          ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name);
02464          if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY) || 
02465              (!ast_tvzero(chan->dtmf_tv) && 
02466                ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
02467             ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass, chan->name);
02468             ast_frfree(f);
02469             f = &ast_null_frame;
02470          } else {
02471             ast_set_flag(chan, AST_FLAG_IN_DTMF);
02472             chan->dtmf_tv = ast_tvnow();
02473             ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass, chan->name);
02474          }
02475          break;
02476       case AST_FRAME_NULL:
02477          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
02478             struct timeval now = ast_tvnow();
02479             if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
02480                chan->emulate_dtmf_duration = 0;
02481                ast_frfree(f);
02482                f = &chan->dtmff;
02483                f->frametype = AST_FRAME_DTMF_END;
02484                f->subclass = chan->emulate_dtmf_digit;
02485                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02486                chan->dtmf_tv = now;
02487                ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02488                chan->emulate_dtmf_digit = 0;
02489                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
02490             }
02491          }
02492          break;
02493       case AST_FRAME_VOICE:
02494          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
02495           * is reached , because we want to make sure we pass at least one
02496           * voice frame through before starting the next digit, to ensure a gap
02497           * between DTMF digits. */
02498          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
02499             ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02500             chan->emulate_dtmf_digit = 0;
02501          }
02502 
02503          if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02504             if (dropaudio)
02505                ast_read_generator_actions(chan, f);
02506             ast_frfree(f);
02507             f = &ast_null_frame;
02508          }
02509 
02510          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02511             struct timeval now = ast_tvnow();
02512             if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
02513                chan->emulate_dtmf_duration = 0;
02514                ast_frfree(f);
02515                f = &chan->dtmff;
02516                f->frametype = AST_FRAME_DTMF_END;
02517                f->subclass = chan->emulate_dtmf_digit;
02518                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02519                chan->dtmf_tv = now;
02520                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
02521             } else {
02522                /* Drop voice frames while we're still in the middle of the digit */
02523                ast_frfree(f);
02524                f = &ast_null_frame;
02525             }
02526          } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass & chan->nativeformats)) {
02527             /* This frame can't be from the current native formats -- drop it on the
02528                floor */
02529             ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
02530                chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
02531             ast_frfree(f);
02532             f = &ast_null_frame;
02533          } else if ((f->frametype == AST_FRAME_VOICE)) {
02534             if (chan->spies)
02535                queue_frame_to_spies(chan, f, SPY_READ);
02536             
02537             if (chan->monitor && chan->monitor->read_stream ) {
02538                /* XXX what does this do ? */
02539 #ifndef MONITOR_CONSTANT_DELAY
02540                int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
02541                if (jump >= 0) {
02542                   jump = chan->outsmpl - chan->insmpl;
02543                   if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
02544                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
02545                   chan->insmpl += jump + f->samples;
02546                } else
02547                   chan->insmpl+= f->samples;
02548 #else
02549                int jump = chan->outsmpl - chan->insmpl;
02550                if (jump - MONITOR_DELAY >= 0) {
02551                   if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02552                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
02553                   chan->insmpl += jump;
02554                } else
02555                   chan->insmpl += f->samples;
02556 #endif
02557                if (chan->monitor->state == AST_MONITOR_RUNNING) {
02558                   if (ast_writestream(chan->monitor->read_stream, f) < 0)
02559                      ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
02560                }
02561             }
02562 
02563             if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL)
02564                f = &ast_null_frame;
02565 
02566             /* Run generator sitting on the line if timing device not available
02567             * and synchronous generation of outgoing frames is necessary       */
02568             ast_read_generator_actions(chan, f);
02569          }
02570       default:
02571          /* Just pass it on! */
02572          break;
02573       }
02574    } else {
02575       /* Make sure we always return NULL in the future */
02576       chan->_softhangup |= AST_SOFTHANGUP_DEV;
02577       if (chan->generator)
02578          ast_deactivate_generator(chan);
02579       /* End the CDR if appropriate */
02580       if (chan->cdr)
02581          ast_cdr_end(chan->cdr);
02582    }
02583 
02584    /* High bit prints debugging */
02585    if (chan->fin & DEBUGCHAN_FLAG)
02586       ast_frame_dump(chan->name, f, "<<");
02587    chan->fin = FRAMECOUNT_INC(chan->fin);
02588 
02589 done:
02590    ast_channel_unlock(chan);
02591    return f;
02592 }

struct ast_channel* __ast_request_and_dial ( const char *  type,
int  format,
void *  data,
int  timeout,
int *  outstate,
int  callingpres,
const char *  cid_num,
const char *  cid_name,
struct outgoing_helper oh,
char *  uniqueid 
) [read]

Definition at line 3128 of file channel.c.

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

Referenced by ast_pbx_outgoing_app2(), ast_pbx_outgoing_exten2(), ast_request_and_dial(), and parkandannounce_exec().

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

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

Activate a given generator

Definition at line 1903 of file channel.c.

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

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

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

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns number of active/allocated channels

Definition at line 462 of file channel.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and channels.

Referenced by quit_handler().

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

char* ast_alloc_uniqueid ( void   ) 

Create a uniqueid.

Definition at line 728 of file channel.c.

References ast_config_AST_SYSTEM_NAME, ast_mainpid, malloc, and uniqueint.

Referenced by action_originate().

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

int ast_answer ( struct ast_channel chan  ) 

Answer a ringing call.

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

Definition at line 1835 of file channel.c.

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

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

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

void ast_begin_shutdown ( int  hangup  ) 

Initiate system shutdown.

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

Definition at line 449 of file channel.c.

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

Referenced by quit_handler().

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

int ast_best_codec ( int  fmts  ) 

Pick the best audio codec.

Pick the best codec

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

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

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

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

G.726 is standard ADPCM, in RFC3551 packing order

G.726 is standard ADPCM, in AAL2 packing order

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

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

iLBC is not too bad

Speex is free, but computationally more expensive than GSM

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

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

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

Definition at line 674 of file channel.c.

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

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

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

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

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

Make a call.

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

Definition at line 3312 of file channel.c.

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

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

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

void ast_cancel_shutdown ( void   ) 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 474 of file channel.c.

References shutting_down.

Referenced by handle_abort_halt().

00475 {
00476    shutting_down = 0;
00477 }

const char* ast_cause2str ( int  state  ) 

Gives the string form of a given hangup cause.

Gives the string form of a given cause code

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

Definition at line 594 of file channel.c.

References causes, and ast_cause::desc.

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

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

void ast_change_name ( struct ast_channel chan,
char *  newname 
)

Change channel name.

Definition at line 3560 of file channel.c.

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

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

struct ast_channel* ast_channel_alloc ( int  needqueue,
int  state,
const char *  cid_num,
const char *  cid_name,
const char *  acctcode,
const char *  exten,
const char *  context,
const int  amaflag,
const char *  name_fmt,
  ... 
) [read]

Create a new channel structure.

Create a channel structure.

Definition at line 737 of file channel.c.

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

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

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

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

Bridge two channels together.

Bridge two channels together

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

Definition at line 4188 of file channel.c.

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

Referenced by ast_bridge_call().

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

int ast_channel_cmpwhentohangup ( struct ast_channel chan,
time_t  offset 
)

Compare a offset with when to hangup channel.

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

Definition at line 494 of file channel.c.

References ast_channel::whentohangup.

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

int ast_channel_datastore_add ( struct ast_channel chan,
struct ast_datastore datastore 
)

Add a datastore to a channel.

Definition at line 1363 of file channel.c.

References AST_LIST_INSERT_HEAD.

Referenced by speech_create(), and try_calling().

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

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

Create a channel datastore structure.

Definition at line 1302 of file channel.c.

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

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

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

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

Find a datastore on a channel.

Definition at line 1390 of file channel.c.

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

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

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

int ast_channel_datastore_free ( struct ast_datastore datastore  ) 

Free a channel datastore structure.

Definition at line 1324 of file channel.c.

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

Referenced by ast_channel_free(), and try_calling().

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

int ast_channel_datastore_inherit ( struct ast_channel from,
struct ast_channel to 
)

Inherit datastores from a parent to a child.

Definition at line 1346 of file channel.c.

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

Referenced by local_call(), and wait_for_answer().

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

int ast_channel_datastore_remove ( struct ast_channel chan,
struct ast_datastore datastore 
)

Remove a datastore from a channel.

Definition at line 1372 of file channel.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, and AST_LIST_TRAVERSE_SAFE_END.

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

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

int ast_channel_defer_dtmf ( struct ast_channel chan  ) 

Set defer DTMF flag on channel.

Defers DTMF

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

Definition at line 1003 of file channel.c.

References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.

Referenced by __adsi_transmit_messages(), and find_cache().

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

void ast_channel_free ( struct ast_channel chan  ) 

Free a channel structure.

Definition at line 1215 of file channel.c.

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

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

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

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

Inherits channel variable from parent to child channel.

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

Definition at line 3566 of file channel.c.

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

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

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

int ast_channel_make_compatible ( struct ast_channel c0,
struct ast_channel c1 
)

Makes two channel formats compatible.

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

Definition at line 3419 of file channel.c.

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

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

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

int ast_channel_masquerade ( struct ast_channel original,
struct ast_channel clone 
)

Weird function made for call transfers.

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

Definition at line 3479 of file channel.c.

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

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

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

char* ast_channel_reason2str ( int  reason  ) 

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

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

Definition at line 3105 of file channel.c.

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

Referenced by attempt_thread().

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

int ast_channel_register ( const struct ast_channel_tech tech  ) 

Register a new telephony channel in Asterisk.

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

Definition at line 516 of file channel.c.

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

Referenced by load_module(), and unload_module().

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

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

Sends HTML on given channel

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

Definition at line 3407 of file channel.c.

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

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

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

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

Sends a URL on a given link

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

Definition at line 3414 of file channel.c.

References ast_channel_sendhtml(), and AST_HTML_URL.

Referenced by sendurl_exec(), and try_calling().

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

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

Sets an option on a channel.

Sets an option on a channel

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

Definition at line 4452 of file channel.c.

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

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

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

void ast_channel_setwhentohangup ( struct ast_channel chan,
time_t  offset 
)

Set when to hangup channel.

Set when to hang a channel up.

Definition at line 486 of file channel.c.

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

Referenced by action_timeout(), and timeout_write().

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

int ast_channel_spy_add ( struct ast_channel chan,
struct ast_channel_spy spy 
)

Adds a spy to a channel, to begin receiving copies of the channel's audio frames.

Parameters:
chan The channel to add the spy to.
spy A pointer to ast_channel_spy structure describing how the spy is to be used.
Returns:
0 for success, non-zero for failure
Note: This function performs no locking; you must hold the channel's lock before calling this function.

Definition at line 1415 of file channel.c.

References ast_calloc, ast_clear_flag, ast_cond_init(), AST_FORMAT_SLINEAR, ast_getformatname(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_INSERT_TAIL, ast_log(), ast_set_flag, ast_test_flag, ast_channel_spy::chan, CHANSPY_FORMAT_AUDIO, CHANSPY_MIXAUDIO, CHANSPY_READ_VOLADJUST, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, CHANSPY_TRIGGER_READ, CHANSPY_TRIGGER_WRITE, CHANSPY_WRITE_VOLADJUST, ast_channel_spy_queue::format, LOG_DEBUG, LOG_WARNING, option_debug, ast_channel_spy::read_queue, ast_channel::spies, ast_channel_spy::trigger, ast_channel_spy::type, and ast_channel_spy::write_queue.

Referenced by start_spying(), and startmon().

01416 {
01417    /* Link the owner channel to the spy */
01418    spy->chan = chan;
01419 
01420    if (!ast_test_flag(spy, CHANSPY_FORMAT_AUDIO)) {
01421       ast_log(LOG_WARNING, "Could not add channel spy '%s' to channel '%s', only audio format spies are supported.\n",
01422          spy->type, chan->name);
01423       return -1;
01424    }
01425 
01426    if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST) && (spy->read_queue.format != AST_FORMAT_SLINEAR)) {
01427       ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n",
01428          ast_getformatname(spy->read_queue.format));
01429       return -1;
01430    }
01431 
01432    if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST) && (spy->write_queue.format != AST_FORMAT_SLINEAR)) {
01433       ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n",
01434          ast_getformatname(spy->write_queue.format));
01435       return -1;
01436    }
01437 
01438    if (ast_test_flag(spy, CHANSPY_MIXAUDIO) &&
01439        ((spy->read_queue.format != AST_FORMAT_SLINEAR) ||
01440         (spy->write_queue.format != AST_FORMAT_SLINEAR))) {
01441       ast_log(LOG_WARNING, "Cannot provide audio mixing on '%s'-'%s' format spies\n",
01442          ast_getformatname(spy->read_queue.format), ast_getformatname(spy->write_queue.format));
01443       return -1;
01444    }
01445 
01446    if (!chan->spies) {
01447       if (!(chan->spies = ast_calloc(1, sizeof(*chan->spies)))) {
01448          return -1;
01449       }
01450 
01451       AST_LIST_HEAD_INIT_NOLOCK(&chan->spies->list);
01452       AST_LIST_INSERT_HEAD(&chan->spies->list, spy, list);
01453    } else {
01454       AST_LIST_INSERT_TAIL(&chan->spies->list, spy, list);
01455    }
01456 
01457    if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) {
01458       ast_cond_init(&spy->trigger, NULL);
01459       ast_set_flag(spy, CHANSPY_TRIGGER_READ);
01460       ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE);
01461    }
01462 
01463    if (option_debug)
01464       ast_log(LOG_DEBUG, "Spy %s added to channel %s\n",
01465          spy->type, chan->name);
01466 
01467    return 0;
01468 }

void ast_channel_spy_free ( struct ast_channel_spy spy  ) 

Free a spy.

Parameters:
spy The spy to free
Returns:
nothing
Note: This function MUST NOT be called with the spy locked.

Definition at line 1543 of file channel.c.

References ast_cond_destroy(), ast_frfree, AST_LIST_REMOVE_HEAD, ast_mutex_destroy(), ast_test_flag, CHANSPY_DONE, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, f, ast_channel_spy::lock, ast_channel_spy::read_queue, ast_channel_spy::status, ast_channel_spy::trigger, and ast_channel_spy::write_queue.

Referenced by channel_spy(), and mixmonitor_thread().

01544 {
01545    struct ast_frame *f = NULL;
01546 
01547    if (spy->status == CHANSPY_DONE)
01548       return;
01549 
01550    /* Switch status to done in case we get called twice */
01551    spy->status = CHANSPY_DONE;
01552 
01553    /* Drop any frames in the queue */
01554    while ((f = AST_LIST_REMOVE_HEAD(&spy->write_queue.list, frame_list)))
01555       ast_frfree(f);
01556    while ((f = AST_LIST_REMOVE_HEAD(&spy->read_queue.list, frame_list)))
01557       ast_frfree(f);
01558 
01559    /* Destroy the condition if in use */
01560    if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
01561       ast_cond_destroy(&spy->trigger);
01562 
01563    /* Destroy our mutex since it is no longer in use */
01564    ast_mutex_destroy(&spy->lock);
01565 
01566    return;
01567 }

struct ast_frame* ast_channel_spy_read_frame ( struct ast_channel_spy spy,
unsigned int  samples 
) [read]

Read one (or more) frames of audio from a channel being spied upon.

Parameters:
spy The spy to operate on
samples The number of audio samples to read
Returns:
NULL for failure, one ast_frame pointer, or a chain of ast_frame pointers
This function can return multiple frames if the spy structure needs to be 'flushed' due to mismatched queue lengths, or if the spy structure is configured to return unmixed audio (in which case each call to this function will return a frame of audio from each side of channel).

Note: This function performs no locking; you must hold the spy's lock before calling this function. You must not hold the channel's lock at the same time.

Definition at line 4771 of file channel.c.

References ast_clear_flag, ast_codec_get_len(), ast_frame_adjust_volume(), ast_frame_slinear_sum(), AST_FRAME_VOICE, ast_frdup(), ast_frfree, AST_LIST_FIRST, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_NEXT, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_test_flag, CHANSPY_MIXAUDIO, CHANSPY_READ_VOLADJUST, CHANSPY_TRIGGER_FLUSH, CHANSPY_WRITE_VOLADJUST, copy_data_from_queue(), ast_channel_spy_queue::format, ast_frame::frametype, ast_channel_spy::read_queue, ast_channel_spy::read_vol_adjustment, ast_channel_spy_queue::samples, ast_channel_spy::write_queue, and ast_channel_spy::write_vol_adjustment.

Referenced by mixmonitor_thread(), and spy_generate().

04772 {
04773    struct ast_frame *result;
04774    /* buffers are allocated to hold SLINEAR, which is the largest format */
04775         short read_buf[samples];
04776         short write_buf[samples];
04777    struct ast_frame *read_frame;
04778    struct ast_frame *write_frame;
04779    int need_dup;
04780    struct ast_frame stack_read_frame = { .frametype = AST_FRAME_VOICE,
04781                      .subclass = spy->read_queue.format,
04782                      .data = read_buf,
04783                      .samples = samples,
04784                      .datalen = ast_codec_get_len(spy->read_queue.format, samples),
04785    };
04786    struct ast_frame stack_write_frame = { .frametype = AST_FRAME_VOICE,
04787                       .subclass = spy->write_queue.format,
04788                       .data = write_buf,
04789                       .samples = samples,
04790                       .datalen = ast_codec_get_len(spy->write_queue.format, samples),
04791    };
04792 
04793    /* if a flush has been requested, dump everything in whichever queue is larger */
04794    if (ast_test_flag(spy, CHANSPY_TRIGGER_FLUSH)) {
04795       if (spy->read_queue.samples > spy->write_queue.samples) {
04796          if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST)) {
04797             AST_LIST_TRAVERSE(&spy->read_queue.list, result, frame_list)
04798                ast_frame_adjust_volume(result, spy->read_vol_adjustment);
04799          }
04800          result = AST_LIST_FIRST(&spy->read_queue.list);
04801          AST_LIST_HEAD_SET_NOLOCK(&spy->read_queue.list, NULL);
04802          spy->read_queue.samples = 0;
04803       } else {
04804          if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) {
04805             AST_LIST_TRAVERSE(&spy->write_queue.list, result, frame_list)
04806                ast_frame_adjust_volume(result, spy->write_vol_adjustment);
04807          }
04808          result = AST_LIST_FIRST(&spy->write_queue.list);
04809          AST_LIST_HEAD_SET_NOLOCK(&spy->write_queue.list, NULL);
04810          spy->write_queue.samples = 0;
04811       }
04812       ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
04813       return result;
04814    }
04815 
04816    if ((spy->read_queue.samples < samples) || (spy->write_queue.samples < samples))
04817       return NULL;
04818 
04819    /* short-circuit if both head frames have exactly what we want */
04820    if ((AST_LIST_FIRST(&spy->read_queue.list)->samples == samples) &&
04821        (AST_LIST_FIRST(&spy->write_queue.list)->samples == samples)) {
04822       read_frame = AST_LIST_REMOVE_HEAD(&spy->read_queue.list, frame_list);
04823       write_frame = AST_LIST_REMOVE_HEAD(&spy->write_queue.list, frame_list);
04824 
04825       spy->read_queue.samples -= samples;
04826       spy->write_queue.samples -= samples;
04827 
04828       need_dup = 0;
04829    } else {
04830       copy_data_from_queue(&spy->read_queue, read_buf, samples);
04831       copy_data_from_queue(&spy->write_queue, write_buf, samples);
04832 
04833       read_frame = &stack_read_frame;
04834       write_frame = &stack_write_frame;
04835       need_dup = 1;
04836    }
04837    
04838    if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST))
04839       ast_frame_adjust_volume(read_frame, spy->read_vol_adjustment);
04840 
04841    if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST))
04842       ast_frame_adjust_volume(write_frame, spy->write_vol_adjustment);
04843 
04844    if (ast_test_flag(spy, CHANSPY_MIXAUDIO)) {
04845       ast_frame_slinear_sum(read_frame, write_frame);
04846 
04847       if (need_dup)
04848          result = ast_frdup(read_frame);
04849       else {
04850          result = read_frame;
04851          ast_frfree(write_frame);
04852       }
04853    } else {
04854       if (need_dup) {
04855          result = ast_frdup(read_frame);
04856          AST_LIST_NEXT(result, frame_list) = ast_frdup(write_frame);
04857       } else {
04858          result = read_frame;
04859          AST_LIST_NEXT(result, frame_list) = write_frame;
04860       }
04861    }
04862 
04863    return result;
04864 }

void ast_channel_spy_remove ( struct ast_channel chan,
struct ast_channel_spy spy 
)

Remove a spy from a channel.

Parameters:
chan The channel to remove the spy from
spy The spy to be removed
Returns:
nothing
Note: This function performs no locking; you must hold the channel's lock before calling this function.

Definition at line 1533 of file channel.c.

References AST_LIST_REMOVE, ast_channel::spies, spy_cleanup(), and spy_detach().

Referenced by channel_spy().

01534 {
01535    if (!chan->spies)
01536       return;
01537 
01538    AST_LIST_REMOVE(&chan->spies->list, spy, list);
01539    spy_detach(spy, chan);
01540    spy_cleanup(chan);
01541 }

void ast_channel_spy_stop_by_type ( struct ast_channel chan,
const char *  type 
)

Find all spies of a particular type on a channel and stop them.

Parameters:
chan The channel to operate on
type A character string identifying the type of spies to be stopped
Returns:
nothing
Note: This function performs no locking; you must hold the channel's lock before calling this function.

Definition at line 1504 of file channel.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, CHANSPY_RUNNING, ast_channel::spies, spy_cleanup(), spy_detach(), ast_channel_spy::status, and ast_channel_spy::type.

Referenced by mixmonitor_cli(), and stop_mixmonitor_exec().

01505 {
01506    struct ast_channel_spy *spy = NULL;
01507    
01508    if (!chan->spies)
01509       return;
01510 
01511    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) {
01512       if ((spy->type == type) && (spy->status == CHANSPY_RUNNING)) {
01513          AST_LIST_REMOVE_CURRENT(&chan->spies->list, list);
01514          spy_detach(spy, chan);
01515       }
01516    }
01517    AST_LIST_TRAVERSE_SAFE_END
01518    spy_cleanup(chan);
01519 }

void ast_channel_spy_trigger_wait ( struct ast_channel_spy spy  ) 

Efficiently wait until audio is available for a spy, or an exception occurs.

Parameters:
spy The spy to wait on
Returns:
nothing
Note: The locking rules for this function are non-obvious... first, you must not hold the channel's lock when calling this function. Second, you must hold the spy's lock before making the function call; while the function runs the lock will be released, and when the trigger event occurs, the lock will be re-obtained. This means that when control returns to your code, you will again hold the spy's lock.

Definition at line 1521 of file channel.c.

References ast_cond_timedwait(), ast_tvadd(), ast_channel_spy::lock, and ast_channel_spy::trigger.

Referenced by mixmonitor_thread().

01522 {
01523    struct timeval tv;
01524    struct timespec ts;
01525 
01526    tv = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000));
01527    ts.tv_sec = tv.tv_sec;
01528    ts.tv_nsec = tv.tv_usec * 1000;
01529 
01530    ast_cond_timedwait(&spy->trigger, &spy->lock, &ts);
01531 }

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

Starts a silence generator on the given channel.

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

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

Definition at line 4903 of file channel.c.

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

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

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

void ast_channel_stop_silence_generator ( struct ast_channel chan,
struct ast_silence_generator state 
)

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

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

Definition at line 4927 of file channel.c.

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

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

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

int ast_channel_supports_html ( struct ast_channel channel  ) 

Checks for HTML support on a channel

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

Definition at line 3402 of file channel.c.

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

Referenced by sendurl_exec(), and try_calling().

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

void ast_channel_undefer_dtmf ( struct ast_channel chan  ) 

Unset defer DTMF flag on channel.

Undeos a defer

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

Definition at line 1015 of file channel.c.

References ast_clear_flag, and AST_FLAG_DEFER_DTMF.

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

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

void ast_channel_unregister ( const struct ast_channel_tech tech  ) 

Unregister a channel technology.

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

Definition at line 548 of file channel.c.

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

Referenced by __unload_module(), and unload_module().

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

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

int ast_channel_whisper_feed ( struct ast_channel chan,
struct ast_frame f 
)

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

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

Definition at line 5160 of file channel.c.

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

Referenced by channel_spy().

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

int ast_channel_whisper_start ( struct ast_channel chan  ) 

Begin 'whispering' onto a channel.

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

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

Definition at line 5145 of file channel.c.

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

Referenced by channel_spy().

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

void ast_channel_whisper_stop ( struct ast_channel chan  ) 

Stop 'whispering' onto a channel.

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

Definition at line 5172 of file channel.c.

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

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

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

void ast_channels_init ( void   ) 

Provided by channel.c

Definition at line 4704 of file channel.c.

References ast_cli_register_multiple(), and cli_channel.

Referenced by main().

04705 {
04706    ast_cli_register_multiple(cli_channel, sizeof(cli_channel) / sizeof(struct ast_cli_entry));
04707 }

struct ast_variable* ast_channeltype_list ( void   )  [read]

return an ast_variable list of channeltypes

Definition at line 182 of file channel.c.

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

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

int ast_check_hangup ( struct ast_channel chan  ) 

Checks to see if a channel is needing hang up.

Check to see if a channel is needing hang up.

Definition at line 404 of file channel.c.

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

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

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

static int ast_check_hangup_locked ( struct ast_channel chan  )  [static]

Definition at line 418 of file channel.c.

References ast_channel_lock, ast_channel_unlock, and ast_check_hangup().

Referenced by ast_channel_bridge().

00419 {
00420    int res;
00421    ast_channel_lock(chan);
00422    res = ast_check_hangup(chan);
00423    ast_channel_unlock(chan);
00424    return res;
00425 }

void ast_deactivate_generator ( struct ast_channel chan  ) 

int ast_do_masquerade ( struct ast_channel original  ) 

Masquerade a channel.

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

Note:
Assumes channel will be locked when called

Definition at line 3640 of file channel.c.

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

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

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

static enum ast_bridge_result ast_generic_bridge ( struct ast_channel c0,
struct ast_channel c1,
struct ast_bridge_config config,
struct ast_frame **  fo,
struct ast_channel **  rc,
struct timeval  bridge_end 
) [static]

Definition at line 4042 of file channel.c.

References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_indicate_data(), ast_jb_do_usecheck(), ast_jb_get_and_deliver(), ast_jb_get_when_to_wakeup(), ast_jb_put(), ast_log(), ast_read(), AST_SOFTHANGUP_UNBRIDGE, ast_waitfor_n(), ast_write(), ast_frame::data, ast_frame::datalen, f, ast_bridge_config::flags, ast_frame::frametype, LOG_DEBUG, ast_channel::nativeformats, option_debug, ast_frame::subclass, ast_channel::tech_pvt, and ast_bridge_config::timelimit.

Referenced by ast_channel_bridge().

04045 {
04046    /* Copy voice back and forth between the two channels. */
04047    struct ast_channel *cs[3];
04048    struct ast_frame *f;
04049    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
04050    int o0nativeformats;
04051    int o1nativeformats;
04052    int watch_c0_dtmf;
04053    int watch_c1_dtmf;
04054    void *pvt0, *pvt1;
04055    /* Indicates whether a frame was queued into a jitterbuffer */
04056    int frame_put_in_jb = 0;
04057    int jb_in_use;
04058    int to;
04059    
04060    cs[0] = c0;
04061    cs[1] = c1;
04062    pvt0 = c0->tech_pvt;
04063    pvt1 = c1->tech_pvt;
04064    o0nativeformats = c0->nativeformats;
04065    o1nativeformats = c1->nativeformats;
04066    watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
04067    watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
04068 
04069    /* Check the need of a jitterbuffer for each channel */
04070    jb_in_use = ast_jb_do_usecheck(c0, c1);
04071 
04072    for (;;) {
04073       struct ast_channel *who, *other;
04074 
04075       if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
04076           (o0nativeformats != c0->nativeformats) ||
04077           (o1nativeformats != c1->nativeformats)) {
04078          /* Check for Masquerade, codec changes, etc */
04079          res = AST_BRIDGE_RETRY;
04080          break;
04081       }
04082       if (bridge_end.tv_sec) {
04083          to = ast_tvdiff_ms(bridge_end, ast_tvnow());
04084          if (to <= 0) {
04085             if (config->timelimit)
04086                res = AST_BRIDGE_RETRY;
04087             else
04088                res = AST_BRIDGE_COMPLETE;
04089             break;
04090          }
04091       } else
04092          to = -1;
04093       /* Calculate the appropriate max sleep interval - in general, this is the time,
04094          left to the closest jb delivery moment */
04095       if (jb_in_use)
04096          to = ast_jb_get_when_to_wakeup(c0, c1, to);
04097       who = ast_waitfor_n(cs, 2, &to);
04098       if (!who) {
04099          /* No frame received within the specified timeout - check if we have to deliver now */
04100          if (jb_in_use)
04101             ast_jb_get_and_deliver(c0, c1);
04102          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
04103             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04104                c0->_softhangup = 0;
04105             if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04106                c1->_softhangup = 0;
04107             c0->_bridge = c1;
04108             c1->_bridge = c0;
04109          }
04110          continue;
04111       }
04112       f = ast_read(who);
04113       if (!f) {
04114          *fo = NULL;
04115          *rc = who;
04116          if (option_debug)
04117             ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
04118          break;
04119       }
04120 
04121       other = (who == c0) ? c1 : c0; /* the 'other' channel */
04122       /* Try add the frame info the who's bridged channel jitterbuff */
04123       if (jb_in_use)
04124          frame_put_in_jb = !ast_jb_put(other, f);
04125 
04126       if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
04127          int bridge_exit = 0;
04128 
04129          switch (f->subclass) {
04130          case AST_CONTROL_HOLD:
04131          case AST_CONTROL_UNHOLD:
04132          case AST_CONTROL_VIDUPDATE:
04133             ast_indicate_data(other, f->subclass, f->data, f->datalen);
04134             break;
04135          default:
04136             *fo = f;
04137             *rc = who;
04138             bridge_exit = 1;
04139             if (option_debug)
04140                ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
04141             break;
04142          }
04143          if (bridge_exit)
04144             break;
04145       }
04146       if ((f->frametype == AST_FRAME_VOICE) ||
04147           (f->frametype == AST_FRAME_DTMF_BEGIN) ||
04148           (f->frametype == AST_FRAME_DTMF) ||
04149           (f->frametype == AST_FRAME_VIDEO) ||
04150           (f->frametype == AST_FRAME_IMAGE) ||
04151           (f->frametype == AST_FRAME_HTML) ||
04152           (f->frametype == AST_FRAME_MODEM) ||
04153           (f->frametype == AST_FRAME_TEXT)) {
04154          /* monitored dtmf causes exit from bridge */
04155          int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
04156 
04157          if (monitored_source && 
04158             (f->frametype == AST_FRAME_DTMF_END || 
04159             f->frametype == AST_FRAME_DTMF_BEGIN)) {
04160             *fo = f;
04161             *rc = who;
04162             if (option_debug)
04163                ast_log(LOG_DEBUG, "Got DTMF %s on channel (%s)\n", 
04164                   f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
04165                   who->name);
04166             break;
04167          }
04168          /* Write immediately frames, not passed through jb */
04169          if (!frame_put_in_jb)
04170             ast_write(other, f);
04171             
04172          /* Check if we have to deliver now */
04173          if (jb_in_use)
04174             ast_jb_get_and_deliver(c0, c1);
04175       }
04176       /* XXX do we want to pass on also frames not matched above ? */
04177       ast_frfree(f);
04178 
04179       /* Swap who gets priority */
04180       cs[2] = cs[0];
04181       cs[0] = cs[1];
04182       cs[1] = cs[2];
04183    }
04184    return res;
04185 }

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

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

Definition at line 1156 of file channel.c.

References channel_find_locked().

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

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

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

Get channel by name prefix and lock it.

Get channel by name prefix (locks channel).

Definition at line 1143 of file channel.c.

References channel_find_locked().

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

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

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

Get channel by uniqueid (locks channel)

Definition at line 1168 of file channel.c.

References channel_find_locked().

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

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

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

Get a channel technology structure by name.

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

Definition at line 571 of file channel.c.

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

Referenced by ast_device_state().

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

ast_group_t ast_get_group ( const char *  s  ) 

Definition at line 4625 of file channel.c.

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

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

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

int ast_hangup ( struct ast_channel chan  ) 

Hangup a channel.

Hang up a channel.

Definition at line 1745 of file channel.c.

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

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

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

int ast_indicate ( struct ast_channel chan,
int  condition 
)

Indicates condition of channel.

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

Definition at line 2612 of file channel.c.

References ast_indicate_data().

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

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

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

Indicates condition of channel, with payload.

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

Definition at line 2617 of file channel.c.

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

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

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

void ast_install_music_functions ( int(*)(struct ast_channel *, const char *, const char *)  start_ptr,
void(*)(struct ast_channel *)  stop_ptr,
void(*)(struct ast_channel *)  cleanup_ptr 
)

Definition at line 4661 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by load_module(), and reload().

04664 {
04665    ast_moh_start_ptr = start_ptr;
04666    ast_moh_stop_ptr = stop_ptr;
04667    ast_moh_cleanup_ptr = cleanup_ptr;
04668 }

int ast_internal_timing_enabled ( struct ast_channel chan  ) 

Check if the channel can run in internal timing mode.

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

Definition at line 2594 of file channel.c.

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

Referenced by add_sdp(), and ast_read_generator_actions().

02595 {
02596    int ret = ast_opt_internal_timing && chan->timingfd > -1;
02597    if (option_debug > 4)
02598       ast_log(LOG_DEBUG, "Internal timing is %s (option_internal_timing=%d chan->timingfd=%d)\n", ret? "enabled": "disabled", ast_opt_internal_timing, chan->timingfd);
02599    return ret;
02600 }

static AST_LIST_HEAD_NOLOCK_STATIC ( backends  ,
chanlist   
) [static]

the list of registered channel types

static AST_LIST_HEAD_STATIC ( channels  ,
ast_channel   
) [static]

the list of channels we have. Note that the lock for this list is used for both the channels list and the backends list.

void ast_moh_cleanup ( struct ast_channel chan  ) 

Definition at line 4698 of file channel.c.

References ast_moh_cleanup_ptr.

Referenced by ast_channel_free().

04699 {
04700    if (ast_moh_cleanup_ptr)
04701       ast_moh_cleanup_ptr(chan);
04702 }

int ast_moh_start ( struct ast_channel chan,
const char *  mclass,
const char *  interpclass 
)

Turn on music on hold on a given channel.

Parameters:
chan The channel structure that will get music on hold
mclass The class to use if the musicclass is not currently set on the channel structure.
interpclass The class to use if the musicclass is not currently set on the channel structure or in the mclass argument.
Return values:
0 success
non-zero failure

Definition at line 4678 of file channel.c.

References ast_moh_start_ptr, ast_verbose(), option_verbose, and VERBOSE_PREFIX_3.

Referenced by alsa_indicate(), app_exec(), ast_autoanswer_login(), ast_hold_call(), cb_events(), conf_run(), feature_exec_app(), gtalk_indicate(), handle_setmusic(), iax2_indicate(), local_indicate(), mgcp_indicate(), misdn_indication(), moh0_exec(), moh1_exec(), moh3_exec(), oh323_indicate(), oss_indicate(), phone_indicate(), queue_exec(), retrydial_exec(), say_periodic_announcement(), say_position(), sip_indicate(), skinny_indicate(), and zt_indicate().

04679 {
04680    if (ast_moh_start_ptr)
04681       return ast_moh_start_ptr(chan, mclass, interpclass);
04682 
04683    if (option_verbose > 2) {
04684       ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n", 
04685          mclass ? mclass : (interpclass ? interpclass : "default"));
04686    }
04687 
04688    return 0;
04689 }

void ast_moh_stop ( struct ast_channel chan  ) 

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

Print call group and pickup group ---.

print call- and pickup groups into buffer

Definition at line 4710 of file channel.c.

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

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

int ast_prod ( struct ast_channel chan  ) 

Send empty audio to prime a channel driver.

Definition at line 2798 of file channel.c.

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

Referenced by ast_activate_generator().

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

int ast_queue_control ( struct ast_channel chan,
enum ast_control_frame_type  control 
)

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

Queue a control frame with payload.

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

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

Definition at line 990 of file channel.c.

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

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

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

int ast_queue_frame ( struct ast_channel chan,
struct ast_frame fin 
)

Queue an outgoing media frame.

Queue an outgoing frame.

Definition at line 912 of file channel.c.

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

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

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

int ast_queue_hangup ( struct ast_channel chan  ) 

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

Reads a frame.

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

Definition at line 2602 of file channel.c.

References __ast_read().

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

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

static void ast_read_generator_actions ( struct ast_channel chan,
struct ast_frame f 
) [static]

Definition at line 2198 of file channel.c.

References ast_deactivate_generator(), AST_FRAME_CNG, ast_internal_timing_enabled(), ast_log(), ast_settimeout(), ast_frame::datalen, ast_frame::frametype, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, LOG_DEBUG, option_debug, ast_frame::samples, ast_channel::timingfd, and ast_channel::timingfunc.

Referenced by __ast_read().

02199 {
02200    if (chan->generatordata &&  !ast_internal_timing_enabled(chan)) {
02201       void *tmp = chan->generatordata;
02202       int res;
02203 
02204       if (chan->timingfunc) {
02205          if (option_debug > 1)
02206             ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
02207          ast_settimeout(chan, 0, NULL, NULL);
02208       }
02209 
02210       chan->generatordata = NULL;     /* reset, to let writes go through */
02211       res = chan->generator->generate(chan, tmp, f->datalen, f->samples);
02212       chan->generatordata = tmp;
02213       if (res) {
02214          if (option_debug > 1)
02215             ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
02216          ast_deactivate_generator(chan);
02217       }
02218 
02219    } else if (f->frametype == AST_FRAME_CNG) {
02220       if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
02221          if (option_debug > 1)
02222             ast_log(LOG_DEBUG, "Generator got CNG, switching to timed mode\n");
02223          ast_settimeout(chan, 160, generator_force, chan);
02224       }
02225    }
02226 }

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

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

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

Definition at line 2607 of file channel.c.

References __ast_read().

Referenced by conf_run().

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

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

Reads multiple digits

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

Definition at line 3354 of file channel.c.

References ast_readstring_full().

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

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

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

Definition at line 3359 of file channel.c.

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

Referenced by ast_app_getdata_full(), and ast_readstring().

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

int ast_recvchar ( struct ast_channel chan,
int  timeout 
)

Receives a text character from a channel.

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

Definition at line 2678 of file channel.c.

References ast_recvtext(), and free.

Referenced by handle_recvchar().

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

char* ast_recvtext ( struct ast_channel chan,
int  timeout 
)

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

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

Definition at line 2689 of file channel.c.

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

Referenced by ast_recvchar(), and handle_recvtext().

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

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

Requests a channel.

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

Definition at line 3307 of file channel.c.

References ast_request_with_uniqueid().

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

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

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

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

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

Definition at line 3252 of file channel.c.

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_exten2().

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

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

Requests a channel.

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

Definition at line 3257 of file channel.c.

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

Referenced by __ast_request_and_dial(), and ast_request().

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

int ast_safe_sleep ( struct ast_channel chan,
int  ms 
)

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

Wait, look for hangups and condition arg.

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

Definition at line 1174 of file channel.c.

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

Referenced by __login_exec(), and ast_safe_sleep().

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

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

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

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

Definition at line 428 of file channel.c.

References ast_malloc, and len.

Referenced by features_new(), and zt_new().

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

int ast_say_character_str ( struct ast_channel chan,
const char *  str,
const char *  ints,
const char *  lang 
)

Definition at line 5124 of file channel.c.

References ast_say_character_str_full.

Referenced by common_exec(), pbx_builtin_saycharacters(), play_mailbox_owner(), rpt_exec(), rpt_tele_thread(), and saycharstr().

05126 {
05127         return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
05128 }

int ast_say_digit_str ( struct ast_channel chan,
const char *  str,
const char *  ints,
const char *  lang 
)

Definition at line 5118 of file channel.c.

References ast_say_digit_str_full.

Referenced by invent_message(), mgcp_ss(), pbx_builtin_saydigits(), play_message_callerid(), and ss_thread().

05120 {
05121         return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
05122 }

int ast_say_digits ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  lang 
)

Definition at line 5112 of file channel.c.

References ast_say_digits_full().

Referenced by common_exec(), conf_exec(), park_call_full(), parkandannounce_exec(), and rpt_tele_thread().

05114 {
05115         return ast_say_digits_full(chan, num, ints, lang, -1, -1);
05116 }

int ast_say_digits_full ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  lang,
int  audiofd,
int  ctrlfd 
)

int ast_say_enumeration ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
const char *  options 
)

int ast_say_number ( struct ast_channel chan,
int  num,
const char *  ints,
const char *  language,
const char *  options 
)

int ast_say_phonetic_str ( struct ast_channel chan,
const char *  str,
const char *  ints,
const char *  lang 
)

Definition at line 5130 of file channel.c.

References ast_say_phonetic_str_full.

Referenced by pbx_builtin_sayphonetic().

05132 {
05133         return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
05134 }

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

"Requests" a channel for sending a message

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

Definition at line 4944 of file channel.c.

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

Referenced by action_message(), and attempt_thread().

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

int ast_senddigit ( struct ast_channel chan,
char  digit 
)

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

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

Definition at line 2788 of file channel.c.

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

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

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

int ast_senddigit_begin ( struct ast_channel chan,
char  digit 
)

Definition at line 2729 of file channel.c.

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

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

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

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

Definition at line 2775 of file channel.c.

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

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

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

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

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

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

Definition at line 2716 of file channel.c.

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

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

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

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

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

Definition at line 3930 of file channel.c.

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

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

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

int ast_set_read_format ( struct ast_channel chan,
int  format 
)

void ast_set_variables ( struct ast_channel chan,
struct ast_variable vars 
)

adds a list of channel variables to a channel

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

Definition at line 4735 of file channel.c.

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

Referenced by __ast_request_and_dial(), ast_pbx_outgoing_app2(), and ast_pbx_outgoing_exten2().

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

int ast_set_write_format ( struct ast_channel chan,
int  format 
)

int ast_setstate ( struct ast_channel chan,
enum ast_channel_state  state 
)

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

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

Definition at line 3968 of file channel.c.

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

Referenced by ast_setstate().

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

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

Definition at line 2107 of file channel.c.

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

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

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

int ast_shutting_down ( void   ) 

Returns non-zero if Asterisk is being shut down.

Returns non-zero if Asterisk is being shut down

Definition at line 480 of file channel.c.

References shutting_down.

Referenced by handle_request_options().

00481 {
00482    return shutting_down;
00483 }

int ast_softhangup ( struct ast_channel chan,
int  cause 
)

int ast_softhangup_nolock ( struct ast_channel chan,
int  cause 
)

Softly hangup a channel, don't lock.

Softly hangup up a channel (no channel lock).

Definition at line 1586 of file channel.c.

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

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

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

char* ast_state2str ( enum  ast_channel_state  ) 

Gives the string form of a given channel state.

Gives the string form of a given channel state

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

Definition at line 619 of file channel.c.

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

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

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

int ast_str2cause ( const char *  name  ) 

Convert a symbolic hangup cause to number.

Convert the string form of a cause code to a number

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

Definition at line 607 of file channel.c.

References causes.

Referenced by pbx_builtin_hangup().

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

AST_THREADSTORAGE ( state2str_threadbuf  ,
state2str_threadbuf_init   
)

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

Play a tone pair for a given amount of time

Definition at line 4607 of file channel.c.

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

Referenced by zapateller_exec().

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

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

Start a tone going

Definition at line 4589 of file channel.c.

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

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

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

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 4602 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

04603 {
04604    ast_deactivate_generator(chan);
04605 }

int ast_transfer ( struct ast_channel chan,
char *  dest 
)

Transfer a call to dest, if the channel supports transfer.

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

Called by:

  • app_transfer
  • the manager interface

Definition at line 3336 of file channel.c.

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

Referenced by transfer_exec().

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

char* ast_transfercapability2str ( int  transfercapability  )  const

Gives the string form of a given transfer capability.

Gives the string form of a given transfer capability

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

Definition at line 653 of file channel.c.

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

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

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

void ast_uninstall_music_functions ( void   ) 

Definition at line 4670 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

04671 {
04672    ast_moh_start_ptr = NULL;
04673    ast_moh_stop_ptr = NULL;
04674    ast_moh_cleanup_ptr = NULL;
04675 }

int ast_waitfor ( struct ast_channel chan,
int  ms 
)

Wait for input on a channel.

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

Definition at line 2091 of file channel.c.

References ast_waitfor_nandfds().

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

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

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

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

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

Definition at line 2086 of file channel.c.

References ast_waitfor_nandfds().

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

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

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

Wait for x amount of time on a file descriptor to have input.

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

Definition at line 1931 of file channel.c.

References ast_waitfor_nandfds().

Referenced by dundi_lookup_internal(), and dundi_precache_internal().

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

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

Wait for x amount of time on a file descriptor to have input.

Waits for activity on a group of channels.

Definition at line 1939 of file channel.c.

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

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

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

int ast_waitfordigit ( struct ast_channel c,
int  ms 
)

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

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

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

Definition at line 2126 of file channel.c.

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

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

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

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

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

Definition at line 1162 of file channel.c.

References channel_find_locked().

Referenced by next_channel().

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

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

Get next channel by name prefix and lock it.

Get channel by name prefix (locks channel).

Definition at line 1149 of file channel.c.

References channel_find_locked().

Referenced by next_channel().

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

int ast_write ( struct ast_channel chan,
struct ast_frame frame 
)

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

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

Todo:
XXX should return 0 maybe ?

Definition at line 2827 of file channel.c.

References ast_channel::_softhangup, ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_deactivate_generator(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WHISPER, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, AST_FORMAT_SLINEAR, ast_frame_adjust_volume(), AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_MODEM, AST_FRAME_NULL, ast_frame_slinear_sum(), AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_log(), AST_MONITOR_RUNNING, ast_mutex_lock(), ast_mutex_unlock(), ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), ast_set_write_format(), ast_slinfactory_available(), ast_slinfactory_read(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_translator_build_path(), ast_translator_free_path(), ast_writestream(), CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, f, ast_channel::fout, FRAMECOUNT_INC, ast_frame::frametype, ast_channel::generatordata, ast_channel_tech::indicate, ast_channel::insmpl, ast_frame::len, ast_channel_whisper_buffer::lock, LOG_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, option_debug, ast_channel_whisper_buffer::original_format, ast_channel::outsmpl, ast_channel_whisper_buffer::path, queue_frame_to_spies(), ast_channel::rawwriteformat, ast_frame::samples, SEEK_FORCECUR, ast_channel_tech::send_html, ast_channel_tech::send_text, ast_channel_whisper_buffer::sf, ast_channel::spies, SPY_WRITE, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel::whisper, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_video, ast_channel::writeformat, and ast_channel::writetrans.

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

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

int ast_write_video ( struct ast_channel chan,
struct ast_frame frame 
)

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

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

Definition at line 2816 of file channel.c.

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

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

static void bridge_playfile ( struct ast_channel chan,
struct ast_channel peer,
const char *  sound,
int  remain 
) [static]

Definition at line 4008 of file channel.c.

References ast_autoservice_start(), ast_autoservice_stop(), AST_DIGIT_ANY, ast_say_number(), and ast_stream_and_wait().

Referenced by ast_channel_bridge().

04009 {
04010    int min = 0, sec = 0, check;
04011 
04012    check = ast_autoservice_start(peer);
04013    if (check)
04014       return;
04015 
04016    if (remain > 0) {
04017       if (remain / 60 > 1) {
04018          min = remain / 60;
04019          sec = remain % 60;
04020       } else {
04021          sec = remain;
04022       }
04023    }
04024    
04025    if (!strcmp(sound,"timeleft")) { /* Queue support */
04026       ast_stream_and_wait(chan, "vm-youhave", chan->language, "");
04027       if (min) {
04028          ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
04029          ast_stream_and_wait(chan, "queue-minutes", chan->language, "");
04030       }
04031       if (sec) {
04032          ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
04033          ast_stream_and_wait(chan, "queue-seconds", chan->language, "");
04034       }
04035    } else {
04036       ast_stream_and_wait(chan, sound, chan->language, "");
04037    }
04038 
04039    ast_autoservice_stop(peer);
04040 }

static struct ast_channel* channel_find_locked ( const struct ast_channel prev,
const char *  name,
const int  namelen,
const char *  context,
const char *  exten,
const char *  uniqueid 
) [static, read]

Helper function to find channels.

It supports these modes:

prev != NULL : get channel next in list after prev name != NULL : get channel with matching name name != NULL && namelen != 0 : get channel whose name starts with prefix exten != NULL : get channel whose exten or macroexten matches context != NULL && exten != NULL : get channel whose context or macrocontext

It returns with the channel's lock held. If getting the individual lock fails, unlock and retry quickly up to 10 times, then give up.

Note:
XXX Note that this code has cost O(N) because of the need to verify that the object is still on the global list.

XXX also note that accessing fields (e.g. c->name in ast_log()) can only be done with the lock held or someone could delete the object while we work on it. This causes some ugliness in the code. Note that removing the first ast_log() may be harmful, as it would shorten the retry period and possibly cause failures. We should definitely go for a better scheme that is deadlock-free.

Definition at line 1045 of file channel.c.

References ast_channel_trylock, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), channels, ast_channel::context, ast_channel::exten, LOG_DEBUG, ast_channel::macrocontext, ast_channel::macroexten, and option_debug.

Referenced by ast_channel_walk_locked(), ast_get_channel_by_exten_locked(), ast_get_channel_by_name_locked(), ast_get_channel_by_name_prefix_locked(), ast_get_channel_by_uniqueid_locked(), ast_walk_channel_by_exten_locked(), and ast_walk_channel_by_name_prefix_locked().

01048 {
01049    const char *msg = prev ? "deadlock" : "initial deadlock";
01050    int retries;
01051    struct ast_channel *c;
01052    const struct ast_channel *_prev = prev;
01053 
01054    for (retries = 0; retries < 10; retries++) {
01055       int done;
01056       AST_LIST_LOCK(&channels);
01057       AST_LIST_TRAVERSE(&channels, c, chan_list) {
01058          prev = _prev;
01059          if (prev) { /* look for next item */
01060             if (c != prev) /* not this one */
01061                continue;
01062             /* found, prepare to return c->next */
01063             if ((c = AST_LIST_NEXT(c, chan_list)) == NULL) break;
01064             /* If prev was the last item on the channel list, then we just
01065              * want to return NULL, instead of trying to deref NULL in the
01066              * next section.
01067              */
01068             prev = NULL;
01069             /* We want prev to be NULL in case we end up doing more searching through
01070              * the channel list to find the channel (ie: name searching). If we didn't
01071              * set this to NULL the logic would just blow up
01072              * XXX Need a better explanation for this ...
01073              */
01074          }
01075          if (uniqueid) { 
01076              if (!strcasecmp(c->uniqueid, uniqueid))
01077             break;
01078          } else if (name) { /* want match by name */
01079             if ((!namelen && strcasecmp(c->name, name)) ||
01080                 (namelen && strncasecmp(c->name, name, namelen)))
01081                continue;   /* name match failed */
01082          } else if (exten) {
01083             if (context && strcasecmp(c->context, context) &&
01084                 strcasecmp(c->macrocontext, context))
01085                continue;   /* context match failed */
01086             if (strcasecmp(c->exten, exten) &&
01087                 strcasecmp(c->macroexten, exten))
01088                continue;   /* exten match failed */
01089          }
01090          /* if we get here, c points to the desired record */
01091          break;
01092       }
01093       /* exit if chan not found or mutex acquired successfully */
01094       /* this is slightly unsafe, as we _should_ hold the lock to access c->name */
01095       done = c == NULL || ast_channel_trylock(c) == 0;
01096       if (!done) {
01097          if (option_debug)
01098             ast_log(LOG_DEBUG, "Avoiding %s for channel '%p'\n", msg, c);
01099          if (retries == 9) {
01100             /* We are about to fail due to a deadlock, so report this
01101              * while we still have the list lock.
01102              */
01103             if (option_debug)
01104                ast_log(LOG_DEBUG, "Failure, could not lock '%p' after %d retries!\n", c, retries);
01105             /* As we have deadlocked, we will skip this channel and
01106              * see if there is another match.
01107              * NOTE: No point doing this for a full-name match,
01108              * as there can be no more matches.
01109              */
01110             if (!(name && !namelen)) {
01111                prev = c;
01112                retries = -1;
01113             }
01114          }
01115       }
01116       AST_LIST_UNLOCK(&channels);
01117       if (done)
01118          return c;
01119       /* If we reach this point we basically tried to lock a channel and failed. Instead of
01120        * starting from the beginning of the list we can restore our saved pointer to the previous
01121        * channel and start from there.
01122        */
01123       prev = _prev;
01124       usleep(1);  /* give other threads a chance before retrying */
01125    }
01126 
01127    return NULL;
01128 }

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

References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.

Referenced by reload_config().

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

static void clone_variables ( struct ast_channel original,
struct ast_channel clone 
) [static]

Clone channel variables from 'clone' channel into 'original' channel.

All variables except those related to app_groupcount are cloned. Variables are actually _removed_ from 'clone' channel, presumably because it will subsequently be destroyed.

Note:
Assumes locks will be in place on both channels when called.

Definition at line 3618 of file channel.c.

References AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_t::name, ast_var_t::value, and ast_channel::varshead.

Referenced by ast_do_masquerade().

03619 {
03620    struct ast_var_t *current, *newvar;
03621    /* Append variables from clone channel into original channel */
03622    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
03623    if (AST_LIST_FIRST(&clone->varshead))
03624       AST_LIST_APPEND_LIST(&original->varshead, &clone->varshead, entries);
03625 
03626    /* then, dup the varshead list into the clone */
03627    
03628    AST_LIST_TRAVERSE(&original->varshead, current, entries) {
03629       newvar = ast_var_assign(current->name, current->value);
03630       if (newvar)
03631          AST_LIST_INSERT_TAIL(&clone->varshead, newvar, entries);
03632    }
03633 }

static char* complete_channeltypes ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 353 of file channel.c.

References AST_LIST_TRAVERSE, strdup, chanlist::tech, and ast_channel_tech::type.

00354 {
00355    struct chanlist *cl;
00356    int which = 0;
00357    int wordlen;
00358    char *ret = NULL;
00359 
00360    if (pos != 3)
00361       return NULL;
00362 
00363    wordlen = strlen(word);
00364 
00365    AST_LIST_TRAVERSE(&backends, cl, list) {
00366       if (!strncasecmp(word, cl->tech->type, wordlen) && ++which > state) {
00367          ret = strdup(cl->tech->type);
00368          break;
00369       }
00370    }
00371    
00372    return ret;
00373 }

static char* complete_channeltypes_deprecated ( const char *  line,
const char *  word,
int  pos,
int  state 
) [static]

Definition at line 331 of file channel.c.

References AST_LIST_TRAVERSE, strdup, chanlist::tech, and ast_channel_tech::type.

00332 {
00333    struct chanlist *cl;
00334    int which = 0;
00335    int wordlen;
00336    char *ret = NULL;
00337 
00338    if (pos != 2)
00339       return NULL;
00340 
00341    wordlen = strlen(word);
00342 
00343    AST_LIST_TRAVERSE(&backends, cl, list) {
00344       if (!strncasecmp(word, cl->tech->type, wordlen) && ++which > state) {
00345          ret = strdup(cl->tech->type);
00346          break;
00347       }
00348    }
00349    
00350    return ret;
00351 }

static void copy_data_from_queue ( struct ast_channel_spy_queue queue,
short *  buf,
unsigned int  samples 
) [static]

Definition at line 4743 of file channel.c.

References ast_codec_get_len(), ast_frfree, AST_LIST_FIRST, AST_LIST_REMOVE_HEAD, ast_log(), ast_frame::data, ast_frame::datalen, f, ast_channel_spy_queue::format, LOG_ERROR, ast_frame::offset, ast_channel_spy_queue::samples, and ast_frame::samples.

Referenced by ast_channel_spy_read_frame().

04744 {
04745    struct ast_frame *f;
04746    int tocopy;
04747    int bytestocopy;
04748 
04749    while (samples) {
04750       if (!(f = AST_LIST_FIRST(&queue->list))) {
04751          ast_log(LOG_ERROR, "Ran out of frames before buffer filled!\n");
04752          break;
04753       }
04754 
04755       tocopy = (f->samples > samples) ? samples : f->samples;
04756       bytestocopy = ast_codec_get_len(queue->format, tocopy);
04757       memcpy(buf, f->data, bytestocopy);
04758       samples -= tocopy;
04759       buf += tocopy;
04760       f->samples -= tocopy;
04761       f->data += bytestocopy;
04762       f->datalen -= bytestocopy;
04763       f->offset += bytestocopy;
04764       queue->samples -= tocopy;
04765 
04766       if (!f->samples)
04767          ast_frfree(AST_LIST_REMOVE_HEAD(&queue->list, frame_list));
04768    }
04769 }

static void detach_spies ( struct ast_channel chan  )  [static]

Definition at line 1569 of file channel.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_channel::spies, spy_cleanup(), and spy_detach().

Referenced by ast_hangup().

01570 {
01571    struct ast_channel_spy *spy = NULL;
01572 
01573    if (!chan->spies)
01574       return;
01575 
01576    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) {
01577       AST_LIST_REMOVE_CURRENT(&chan->spies->list, list);
01578       spy_detach(spy, chan);
01579    }
01580    AST_LIST_TRAVERSE_SAFE_END
01581 
01582    spy_cleanup(chan);
01583 }

static void free_cid ( struct ast_callerid cid  )  [static]

Definition at line 1200 of file channel.c.

References ast_callerid::cid_ani, ast_callerid::cid_dnid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_rdnis, and free.

Referenced by ast_channel_free().

01201 {
01202    if (cid->cid_dnid)
01203       free(cid->cid_dnid);
01204    if (cid->cid_num)
01205       free(cid->cid_num);  
01206    if (cid->cid_name)
01207       free(cid->cid_name); 
01208    if (cid->cid_ani)
01209       free(cid->cid_ani);
01210    if (cid->cid_rdnis)
01211       free(cid->cid_rdnis);
01212 }

static void free_translation ( struct ast_channel clone  )  [static]

Definition at line 1732 of file channel.c.

References ast_translator_free_path(), ast_channel::nativeformats, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readtrans, and ast_channel::writetrans.

Referenced by ast_do_masquerade(), and ast_hangup().

01733 {
01734    if (clone->writetrans)
01735       ast_translator_free_path(clone->writetrans);
01736    if (clone->readtrans)
01737       ast_translator_free_path(clone->readtrans);
01738    clone->writetrans = NULL;
01739    clone->readtrans = NULL;
01740    clone->rawwriteformat = clone->nativeformats;
01741    clone->rawreadformat = clone->nativeformats;
01742 }

static int generator_force ( const void *  data  )  [static]

Definition at line 1883 of file channel.c.

References ast_deactivate_generator(), ast_log(), ast_generator::generate, ast_channel::generator, ast_channel::generatordata, LOG_DEBUG, and option_debug.

Referenced by ast_activate_generator(), and ast_read_generator_actions().

01884 {
01885    /* Called if generator doesn't have data */
01886    void *tmp;
01887    int res;
01888    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
01889    struct ast_channel *chan = (struct ast_channel *)data;
01890    tmp = chan->generatordata;
01891    chan->generatordata = NULL;
01892    generate = chan->generator->generate;
01893    res = generate(chan, tmp, 0, 160);
01894    chan->generatordata = tmp;
01895    if (res) {
01896       if (option_debug)
01897          ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01898       ast_deactivate_generator(chan);
01899    }
01900    return 0;
01901 }

static void queue_frame_to_spies ( struct ast_channel chan,
struct ast_frame f,
enum spy_direction  dir 
) [static]

Definition at line 1616 of file channel.c.

References ast_clear_flag, ast_cond_signal(), AST_FORMAT_SLINEAR, ast_frdup(), ast_frfree, ast_getformatname(), AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_set_flag, ast_test_flag, ast_translate(), ast_translator_build_path(), ast_translator_free_path(), CHANSPY_RUNNING, CHANSPY_TRIGGER_FLUSH, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, CHANSPY_TRIGGER_READ, CHANSPY_TRIGGER_WRITE, ast_channel_spy_queue::format, channel_spy_trans::last_format, ast_channel_spy::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, option_debug, channel_spy_trans::path, ast_channel_spy::read_queue, ast_channel_spy_list::read_translator, ast_frame::samples, ast_channel_spy_queue::samples, ast_channel::spies, SPY_QUEUE_SAMPLE_LIMIT, SPY_READ, SPY_WRITE, ast_channel_spy::status, ast_frame::subclass, ast_channel_spy::trigger, ast_channel_spy::type, ast_channel_spy::write_queue, and ast_channel_spy_list::write_translator.

Referenced by __ast_read(), and ast_write().

01617 {
01618    struct ast_frame *translated_frame = NULL;
01619    struct ast_channel_spy *spy;
01620    struct channel_spy_trans *trans;
01621 
01622    trans = (dir == SPY_READ) ? &chan->spies->read_translator : &chan->spies->write_translator;
01623 
01624    AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
01625       struct ast_channel_spy_queue *queue;
01626       struct ast_frame *duped_fr;
01627 
01628       if (spy->status != CHANSPY_RUNNING)
01629          continue;
01630 
01631       ast_mutex_lock(&spy->lock);
01632 
01633       queue = (dir == SPY_READ) ? &spy->read_queue : &spy->write_queue;
01634 
01635       if ((queue->format == AST_FORMAT_SLINEAR) && (f->subclass != AST_FORMAT_SLINEAR)) {
01636          if (!translated_frame) {
01637             if (trans->path && (trans->last_format != f->subclass)) {
01638                ast_translator_free_path(trans->path);
01639                trans->path = NULL;
01640             }
01641             if (!trans->path) {
01642                if (option_debug)
01643                   ast_log(LOG_DEBUG, "Building translator from %s to SLINEAR for spies on channel %s\n",
01644                      ast_getformatname(f->subclass), chan->name);
01645                if ((trans->path = ast_translator_build_path(AST_FORMAT_SLINEAR, f->subclass)) == NULL) {
01646                   ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n",
01647                      ast_getformatname(f->subclass), ast_getformatname(AST_FORMAT_SLINEAR));
01648                   ast_mutex_unlock(&spy->lock);
01649                   continue;
01650                } else {
01651                   trans->last_format = f->subclass;
01652                }
01653             }
01654             if (!(translated_frame = ast_translate(trans->path, f, 0))) {
01655                ast_log(LOG_ERROR, "Translation to %s failed, dropping frame for spies\n",
01656                   ast_getformatname(AST_FORMAT_SLINEAR));
01657                ast_mutex_unlock(&spy->lock);
01658                break;
01659             }
01660          }
01661          duped_fr = ast_frdup(translated_frame);
01662       } else if (f->subclass != queue->format) {
01663          ast_log(LOG_WARNING, "Spy '%s' on channel '%s' wants format '%s', but frame is '%s', dropping\n",
01664             spy->type, chan->name,
01665             ast_getformatname(queue->format), ast_getformatname(f->subclass));
01666          ast_mutex_unlock(&spy->lock);
01667          continue;
01668       } else
01669          duped_fr = ast_frdup(f);
01670 
01671       AST_LIST_INSERT_TAIL(&queue->list, duped_fr, frame_list);
01672 
01673       queue->samples += f->samples;
01674 
01675       if (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) {
01676          if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) {
01677             switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) {
01678             case CHANSPY_TRIGGER_READ:
01679                if (dir == SPY_WRITE) {
01680                   ast_set_flag(spy, CHANSPY_TRIGGER_WRITE);
01681                   ast_clear_flag(spy, CHANSPY_TRIGGER_READ);
01682                   if (option_debug)
01683                      ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to write-trigger mode\n",
01684                         spy->type, chan->name);
01685                }
01686                break;
01687             case CHANSPY_TRIGGER_WRITE:
01688                if (dir == SPY_READ) {
01689                   ast_set_flag(spy, CHANSPY_TRIGGER_READ);
01690                   ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE);
01691                   if (option_debug)
01692                      ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to read-trigger mode\n",
01693                         spy->type, chan->name);
01694                }
01695                break;
01696             }
01697             if (option_debug)
01698                ast_log(LOG_DEBUG, "Triggering queue flush for spy '%s' on '%s'\n",
01699                   spy->type, chan->name);
01700             ast_set_flag(spy, CHANSPY_TRIGGER_FLUSH);
01701             ast_cond_signal(&spy->trigger);
01702          } else {
01703             if (option_debug)
01704                ast_log(LOG_DEBUG, "Spy '%s' on channel '%s' %s queue too long, dropping frames\n",
01705                   spy->type, chan->name, (dir == SPY_READ) ? "read" : "write");
01706             while (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) {
01707                struct ast_frame *drop = AST_LIST_REMOVE_HEAD(&queue->list, frame_list);
01708                queue->samples -= drop->samples;
01709                ast_frfree(drop);
01710             }
01711          }
01712       } else {
01713          switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) {
01714          case CHANSPY_TRIGGER_READ:
01715             if (dir == SPY_READ)
01716                ast_cond_signal(&spy->trigger);
01717             break;
01718          case CHANSPY_TRIGGER_WRITE:
01719             if (dir == SPY_WRITE)
01720                ast_cond_signal(&spy->trigger);
01721             break;
01722          }
01723       }
01724 
01725       ast_mutex_unlock(&spy->lock);
01726    }
01727 
01728    if (translated_frame)
01729       ast_frfree(translated_frame);
01730 }

static int set_format ( struct ast_channel chan,
int  fmt,
int *  rawformat,
int *  format,
struct ast_trans_pvt **  trans,
const int  direction 
) [static]

Definition at line 3040 of file channel.c.

References ast_channel_lock, ast_channel_unlock, AST_FORMAT_AUDIO_MASK, ast_getformatname(), ast_log(), ast_translator_best_choice(), ast_translator_build_path(), ast_translator_free_path(), LOG_DEBUG, LOG_WARNING, ast_channel::nativeformats, and option_debug.

Referenced by ast_set_read_format(), and ast_set_write_format().

03042 {
03043    int native;
03044    int res;
03045    
03046    /* Make sure we only consider audio */
03047    fmt &= AST_FORMAT_AUDIO_MASK;
03048    
03049    native = chan->nativeformats;
03050    /* Find a translation path from the native format to one of the desired formats */
03051    if (!direction)
03052       /* reading */
03053       res = ast_translator_best_choice(&fmt, &native);
03054    else
03055       /* writing */
03056       res = ast_translator_best_choice(&native, &fmt);
03057 
03058    if (res < 0) {
03059       ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
03060          ast_getformatname(native), ast_getformatname(fmt));
03061       return -1;
03062    }
03063    
03064    /* Now we have a good choice for both. */
03065    ast_channel_lock(chan);
03066 
03067    if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
03068       /* the channel is already in these formats, so nothing to do */
03069       ast_channel_unlock(chan);
03070       return 0;
03071    }
03072 
03073    *rawformat = native;
03074    /* User perspective is fmt */
03075    *format = fmt;
03076    /* Free any read translation we have right now */
03077    if (*trans)
03078       ast_translator_free_path(*trans);
03079    /* Build a translation path from the raw format to the desired format */
03080    if (!direction)
03081       /* reading */
03082       *trans = ast_translator_build_path(*format, *rawformat);
03083    else
03084       /* writing */
03085       *trans = ast_translator_build_path(*rawformat, *format);
03086    ast_channel_unlock(chan);
03087    if (option_debug)
03088       ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name,
03089          direction ? "write" : "read", ast_getformatname(fmt));
03090    return 0;
03091 }

static int show_channeltype ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 278 of file channel.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_channel_tech::capabilities, channels, ast_channel_tech::devicestate, ast_channel_tech::indicate, LOG_WARNING, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel_tech::send_digit_begin, ast_channel_tech::send_digit_end, ast_channel_tech::send_html, ast_channel_tech::send_image, ast_channel_tech::send_text, chanlist::tech, ast_channel_tech::transfer, and ast_channel_tech::type.

00279 {
00280    struct chanlist *cl = NULL;
00281 
00282    if (argc != 4)
00283       return RESULT_SHOWUSAGE;
00284    
00285    if (AST_LIST_LOCK(&channels)) {
00286       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00287       return RESULT_FAILURE;
00288    }
00289 
00290    AST_LIST_TRAVERSE(&backends, cl, list) {
00291       if (!strncasecmp(cl->tech->type, argv[3], strlen(cl->tech->type))) {
00292          break;
00293       }
00294    }
00295 
00296 
00297    if (!cl) {
00298       ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[3]);
00299       AST_LIST_UNLOCK(&channels);
00300       return RESULT_FAILURE;
00301    }
00302 
00303    ast_cli(fd,
00304       "-- Info about channel driver: %s --\n"
00305       "  Device State: %s\n"
00306       "    Indication: %s\n"
00307       "     Transfer : %s\n"
00308       "  Capabilities: %d\n"
00309       "   Digit Begin: %s\n"
00310       "     Digit End: %s\n"
00311       "    Send HTML : %s\n"
00312       " Image Support: %s\n"
00313       "  Text Support: %s\n",
00314       cl->tech->type,
00315       (cl->tech->devicestate) ? "yes" : "no",
00316       (cl->tech->indicate) ? "yes" : "no",
00317       (cl->tech->transfer) ? "yes" : "no",
00318       (cl->tech->capabilities) ? cl->tech->capabilities : -1,
00319       (cl->tech->send_digit_begin) ? "yes" : "no",
00320       (cl->tech->send_digit_end) ? "yes" : "no",
00321       (cl->tech->send_html) ? "yes" : "no",
00322       (cl->tech->send_image) ? "yes" : "no",
00323       (cl->tech->send_text) ? "yes" : "no"
00324       
00325    );
00326 
00327    AST_LIST_UNLOCK(&channels);
00328    return RESULT_SUCCESS;
00329 }

static int show_channeltype_deprecated ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 225 of file channel.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_channel_tech::capabilities, channels, ast_channel_tech::devicestate, ast_channel_tech::indicate, LOG_WARNING, RESULT_FAILURE, RESULT_SHOWUSAGE, RESULT_SUCCESS, ast_channel_tech::send_digit_begin, ast_channel_tech::send_digit_end, ast_channel_tech::send_html, ast_channel_tech::send_image, ast_channel_tech::send_text, chanlist::tech, ast_channel_tech::transfer, and ast_channel_tech::type.

00226 {
00227    struct chanlist *cl = NULL;
00228 
00229    if (argc != 3)
00230       return RESULT_SHOWUSAGE;
00231    
00232    if (AST_LIST_LOCK(&channels)) {
00233       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00234       return RESULT_FAILURE;
00235    }
00236 
00237    AST_LIST_TRAVERSE(&backends, cl, list) {
00238       if (!strncasecmp(cl->tech->type, argv[2], strlen(cl->tech->type))) {
00239          break;
00240       }
00241    }
00242 
00243 
00244    if (!cl) {
00245       ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[2]);
00246       AST_LIST_UNLOCK(&channels);
00247       return RESULT_FAILURE;
00248    }
00249 
00250    ast_cli(fd,
00251       "-- Info about channel driver: %s --\n"
00252       "  Device State: %s\n"
00253       "    Indication: %s\n"
00254       "     Transfer : %s\n"
00255       "  Capabilities: %d\n"
00256       "   Digit Begin: %s\n"
00257       "     Digit End: %s\n"
00258       "    Send HTML : %s\n"
00259       " Image Support: %s\n"
00260       "  Text Support: %s\n",
00261       cl->tech->type,
00262       (cl->tech->devicestate) ? "yes" : "no",
00263       (cl->tech->indicate) ? "yes" : "no",
00264       (cl->tech->transfer) ? "yes" : "no",
00265       (cl->tech->capabilities) ? cl->tech->capabilities : -1,
00266       (cl->tech->send_digit_begin) ? "yes" : "no",
00267       (cl->tech->send_digit_end) ? "yes" : "no",
00268       (cl->tech->send_html) ? "yes" : "no",
00269       (cl->tech->send_image) ? "yes" : "no",
00270       (cl->tech->send_text) ? "yes" : "no"
00271       
00272    );
00273 
00274    AST_LIST_UNLOCK(&channels);
00275    return RESULT_SUCCESS;
00276 }

static int show_channeltypes ( int  fd,
int  argc,
char *  argv[] 
) [static]

Definition at line 198 of file channel.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), channels, ast_channel_tech::description, ast_channel_tech::devicestate, FORMAT, ast_channel_tech::indicate, LOG_WARNING, RESULT_SUCCESS, chanlist::tech, ast_channel_tech::transfer, and ast_channel_tech::type.

00199 {
00200 #define FORMAT  "%-10.10s  %-40.40s %-12.12s %-12.12s %-12.12s\n"
00201    struct chanlist *cl;
00202    int count_chan = 0;
00203 
00204    ast_cli(fd, FORMAT, "Type", "Description",       "Devicestate", "Indications", "Transfer");
00205    ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
00206    if (AST_LIST_LOCK(&channels)) {
00207       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00208       return -1;
00209    }
00210    AST_LIST_TRAVERSE(&backends, cl, list) {
00211       ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description,
00212          (cl->tech->devicestate) ? "yes" : "no",
00213          (cl->tech->indicate) ? "yes" : "no",
00214          (cl->tech->transfer) ? "yes" : "no");
00215       count_chan++;
00216    }
00217    AST_LIST_UNLOCK(&channels);
00218    ast_cli(fd, "----------\n%d channel drivers registered.\n", count_chan);
00219    return RESULT_SUCCESS;
00220 
00221 #undef FORMAT
00222 
00223 }

static void* silence_generator_alloc ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 4866 of file channel.c.

04867 {
04868    /* just store the data pointer in the channel structure */
04869    return data;
04870 }

static int silence_generator_generate ( struct ast_channel chan,
void *  data,
int  len,
int  samples 
) [static]

Definition at line 4877 of file channel.c.

References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_write(), and ast_frame::frametype.

04878 {
04879    short buf[samples];
04880    struct ast_frame frame = {
04881       .frametype = AST_FRAME_VOICE,
04882       .subclass = AST_FORMAT_SLINEAR,
04883       .data = buf,
04884       .samples = samples,
04885       .datalen = sizeof(buf),
04886    };
04887    memset(buf, 0, sizeof(buf));
04888    if (ast_write(chan, &frame))
04889       return -1;
04890    return 0;
04891 }

static void silence_generator_release ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 4872 of file channel.c.

04873 {
04874    /* nothing to do */
04875 }

static void spy_cleanup ( struct ast_channel chan  )  [static]

static void spy_detach ( struct ast_channel_spy spy,
struct ast_channel chan 
) [static]

Definition at line 1485 of file channel.c.

References ast_cond_signal(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_test_flag, ast_channel_spy::chan, CHANSPY_DONE, CHANSPY_STOP, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, ast_channel_spy::lock, LOG_DEBUG, option_debug, ast_channel_spy::status, ast_channel_spy::trigger, and ast_channel_spy::type.

Referenced by ast_channel_spy_remove(), ast_channel_spy_stop_by_type(), and detach_spies().

01486 {
01487    /* We only need to poke them if they aren't already done */
01488    if (spy->status != CHANSPY_DONE) {
01489       ast_mutex_lock(&spy->lock);
01490       /* Indicate to the spy to stop */
01491       spy->status = CHANSPY_STOP;
01492       spy->chan = NULL;
01493       /* Poke the spy if needed */
01494       if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
01495          ast_cond_signal(&spy->trigger);
01496       if (option_debug)
01497          ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n", spy->type, chan->name);
01498       ast_mutex_unlock(&spy->lock);
01499    }
01500 
01501    return;
01502 }

static void* tonepair_alloc ( struct ast_channel chan,
void *  params 
) [static]

Definition at line 4507 of file channel.c.

References ast_calloc, AST_FLAG_WRITE_INT, AST_FORMAT_SLINEAR, ast_log(), ast_set_flag, ast_set_write_format(), tonepair_def::duration, tonepair_state::duration, tonepair_state::fac1, tonepair_state::fac2, tonepair_def::freq1, tonepair_def::freq2, LOG_WARNING, tonepair_state::modulate, tonepair_state::origwfmt, tonepair_release(), tonepair_state::v1_1, tonepair_state::v2_1, tonepair_state::v2_2, tonepair_state::v3_1, tonepair_state::v3_2, tonepair_def::vol, and ast_channel::writeformat.

04508 {
04509    struct tonepair_state *ts;
04510    struct tonepair_def *td = params;
04511 
04512    if (!(ts = ast_calloc(1, sizeof(*ts))))
04513       return NULL;
04514    ts->origwfmt = chan->writeformat;
04515    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
04516       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
04517       tonepair_release(NULL, ts);
04518       ts = NULL;
04519    } else {
04520       ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
04521       ts->v1_1 = 0;
04522       ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
04523       ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
04524       ts->v2_1 = 0;
04525       ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
04526       ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
04527       ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
04528       ts->duration = td->duration;
04529       ts->modulate = 0;
04530    }
04531    /* Let interrupts interrupt :) */
04532    ast_set_flag(chan, AST_FLAG_WRITE_INT);
04533    return ts;
04534 }

static int tonepair_generator ( struct ast_channel chan,
void *  data,
int  len,
int  samples 
) [static]

Definition at line 4536 of file channel.c.

References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_log(), ast_write(), ast_frame::data, tonepair_state::data, ast_frame::datalen, tonepair_state::duration, tonepair_state::f, tonepair_state::fac1, tonepair_state::fac2, ast_frame::frametype, LOG_WARNING, tonepair_state::modulate, ast_frame::offset, tonepair_state::pos, ast_frame::samples, ast_frame::subclass, tonepair_state::v1_1, tonepair_state::v1_2, tonepair_state::v2_1, tonepair_state::v2_2, tonepair_state::v3_1, and tonepair_state::v3_2.

04537 {
04538    struct tonepair_state *ts = data;
04539    int x;
04540 
04541    /* we need to prepare a frame with 16 * timelen samples as we're
04542     * generating SLIN audio
04543     */
04544    len = samples * 2;
04545 
04546    if (len > sizeof(ts->data) / 2 - 1) {
04547       ast_log(LOG_WARNING, "Can't generate that much data!\n");
04548       return -1;
04549    }
04550    memset(&ts->f, 0, sizeof(ts->f));
04551    for (x=0;x<len/2;x++) {
04552       ts->v1_1 = ts->v2_1;
04553       ts->v2_1 = ts->v3_1;
04554       ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
04555       
04556       ts->v1_2 = ts->v2_2;
04557       ts->v2_2 = ts->v3_2;
04558       ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
04559       if (ts->modulate) {
04560          int p;
04561          p = ts->v3_2 - 32768;
04562          if (p < 0) p = -p;
04563          p = ((p * 9) / 10) + 1;
04564          ts->data[x] = (ts->v3_1 * p) >> 15;
04565       } else
04566          ts->data[x] = ts->v3_1 + ts->v3_2; 
04567    }
04568    ts->f.frametype = AST_FRAME_VOICE;
04569    ts->f.subclass = AST_FORMAT_SLINEAR;
04570    ts->f.datalen = len;
04571    ts->f.samples = samples;
04572    ts->f.offset = AST_FRIENDLY_OFFSET;
04573    ts->f.data = ts->data;
04574    ast_write(chan, &ts->f);
04575    ts->pos += x;
04576    if (ts->duration > 0) {
04577       if (ts->pos >= ts->duration * 8)
04578          return -1;
04579    }
04580    return 0;
04581 }

static void tonepair_release ( struct ast_channel chan,
void *  params 
) [static]

Definition at line 4498 of file channel.c.

References ast_set_write_format(), free, and tonepair_state::origwfmt.

Referenced by tonepair_alloc().

04499 {
04500    struct tonepair_state *ts = params;
04501 
04502    if (chan)
04503       ast_set_write_format(chan, ts->origwfmt);
04504    free(ts);
04505 }


Variable Documentation

void(* ast_moh_cleanup_ptr)(struct ast_channel *) = NULL [static]

int(* ast_moh_start_ptr)(struct ast_channel *, const char *, const char *) = NULL [static]

void(* ast_moh_stop_ptr)(struct ast_channel *) = NULL [static]

struct ast_cause causes[]

struct ast_cli_entry cli_channel[] [static]

Definition at line 393 of file channel.c.

Referenced by ast_channels_init().

Initial value:

 {
   { "show", "channeltype", NULL },
   show_channeltype_deprecated, NULL,
   NULL, complete_channeltypes_deprecated }

Definition at line 388 of file channel.c.

Initial value:

 {
   { "show", "channeltypes", NULL },
   show_channeltypes, NULL,
   NULL }

Definition at line 383 of file channel.c.

unsigned long global_fin

Definition at line 102 of file channel.c.

Referenced by ast_channel_alloc().

unsigned long global_fout

Definition at line 102 of file channel.c.

Referenced by ast_channel_alloc().

struct ast_channel_tech null_tech [static]

Initial value:

 {
   .type = "NULL",
   .description = "Null channel (should not see this)",
}

Definition at line 722 of file channel.c.

Referenced by ast_channel_alloc().

char show_channeltype_usage[] [static]

Initial value:

"Usage: core show channeltype <name>\n"
"  Show details about the specified channel type, <name>.\n"

Definition at line 379 of file channel.c.

char show_channeltypes_usage[] [static]

Initial value:

"Usage: core show channeltypes\n"
"       Lists available channel types registered in your Asterisk server.\n"

Definition at line 375 of file channel.c.

int shutting_down [static]

Prevent new channel allocation if shutting down.

Definition at line 98 of file channel.c.

Referenced by ast_begin_shutdown(), ast_cancel_shutdown(), ast_channel_alloc(), and ast_shutting_down().

Initial value:

Definition at line 4893 of file channel.c.

struct ast_generator tonepair [static]

Initial value:

 {
   alloc: tonepair_alloc,
   release: tonepair_release,
   generate: tonepair_generator,
}

Definition at line 4583 of file channel.c.

Referenced by ast_tonepair_start().

int uniqueint [static]

Definition at line 100 of file channel.c.

Referenced by ast_alloc_uniqueid(), and ast_channel_alloc().


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