Mon May 14 04:45:50 2007

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 MONITOR_CONSTANT_DELAY
#define MONITOR_DELAY   150 * 8
#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)
ast_channel__ast_request_and_dial (const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
int ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params)
int ast_active_channels (void)
 returns number of active/allocated channels
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.
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.
ast_channelast_channel_alloc (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *name_fmt,...)
 Create a channel structure.
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 the settings of when to hang a channel up.
int ast_channel_datastore_add (struct ast_channel *chan, struct ast_datastore *datastore)
 Add a datastore to a channel.
ast_datastoreast_channel_datastore_alloc (const struct ast_datastore_info *info, char *uid)
 Create a channel datastore structure.
ast_datastoreast_channel_datastore_find (struct ast_channel *chan, const struct ast_datastore_info *info, char *uid)
 Find a datastore on a channel.
int ast_channel_datastore_free (struct ast_datastore *datastore)
 Free a channel datastore structure.
int ast_channel_datastore_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.
int ast_channel_register (const struct ast_channel_tech *tech)
 Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
int ast_channel_sendhtml (struct ast_channel *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 hang a channel up.
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.
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.
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.
ast_channelast_channel_walk_locked (const struct ast_channel *prev)
 Browse channels in use Browse the channels currently in use.
int ast_channel_whisper_feed (struct ast_channel *chan, struct ast_frame *f)
 Feed an audio frame into the whisper buffer on a channel.
int ast_channel_whisper_start (struct ast_channel *chan)
 Begin 'whispering' onto a channel.
void ast_channel_whisper_stop (struct ast_channel *chan)
 Stop 'whispering' onto a channel.
void ast_channels_init (void)
ast_variableast_channeltype_list (void)
 return an ast_variable list of channeltypes
int ast_check_hangup (struct ast_channel *chan)
 Check to see if a channel is needing hang up.
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)
 Start masquerading a channel XXX This is a seriously wacked out operation. We're essentially putting the guts of the clone channel into the original channel. Start by killing off the original channel's backend. I'm not sure we're going to keep this function, because while the features are nice, the cost is very high in terms of pure nastiness. XXX.
static 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)
ast_channelast_get_channel_by_exten_locked (const char *exten, const char *context)
 Get channel by exten (and optionally context) and lock it.
ast_channelast_get_channel_by_name_locked (const char *name)
 Get channel by name (locks channel).
ast_channelast_get_channel_by_name_prefix_locked (const char *name, const int namelen)
 Get channel by name prefix (locks channel).
ast_channel_techast_get_channel_tech (const char *name)
 Get a channel technology structure by name.
ast_group_t ast_get_group (const char *s)
int ast_hangup (struct ast_channel *chan)
 Hang up a channel.
int ast_indicate (struct ast_channel *chan, int condition)
 Indicates condition of channel.
int ast_indicate_data (struct ast_channel *chan, int condition, const void *data, size_t datalen)
 Indicates condition of channel, with payload.
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- and pickup groups into buffer
int ast_prod (struct ast_channel *chan)
 Send empty audio to prime a channel driver.
int ast_queue_control (struct ast_channel *chan, enum ast_control_frame_type control)
 Queue a control frame with payload.
int ast_queue_control_data (struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
 Queue a control frame with payload.
int ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin)
 Queue an outgoing frame.
int ast_queue_hangup (struct ast_channel *chan)
 Queue a hangup frame.
ast_frameast_read (struct ast_channel *chan)
 Reads a frame.
ast_frameast_read_noaudio (struct ast_channel *chan)
 Reads a frame, returning AST_FRAME_NULL frame if audio.
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.
ast_channelast_request (const char *type, int format, void *data, int *cause)
 Requests a channel.
ast_channelast_request_and_dial (const char *type, int format, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
 Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
int ast_safe_sleep (struct ast_channel *chan, int ms)
 Wait for a specied amount of time, looking for hangups.
int ast_safe_sleep_conditional (struct ast_channel *chan, int ms, int(*cond)(void *), void *data)
 Wait for a specied amount of time, looking for hangups and a condition argument.
char * ast_safe_string_alloc (const char *fmt,...)
 printf the string into a correctly sized mallocd buffer, and return the buffer
int ast_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_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)
 Send a DTMF digit to a channel Send a DTMF digit to a channel.
int ast_senddigit_end (struct ast_channel *chan, char digit, unsigned int duration)
 Send a DTMF digit to a channel.
int ast_sendtext (struct ast_channel *chan, const char *text)
 Sends text to a channel Write text to a display on a channel.
void ast_set_callerid (struct ast_channel *chan, const char *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_settimeout (struct ast_channel *c, int samples, int(*func)(void *data), void *data)
int ast_shutting_down (void)
 Returns non-zero if Asterisk is being shut down.
int ast_softhangup (struct ast_channel *chan, int cause)
 Softly hangup up a channel.
int ast_softhangup_nolock (struct ast_channel *chan, int cause)
 Softly hangup up a channel (no channel lock).
char * ast_state2str (enum ast_channel_state 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 channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.
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.
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)
 Waits for input on an fd This version works on fd's only. Be careful with it.
ast_channelast_waitfor_nandfds (struct ast_channel **c, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
 Waits for activity on a group of channels.
int ast_waitfordigit (struct ast_channel *c, int ms)
 Waits for a digit.
int ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int cmdfd)
 Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
ast_channelast_walk_channel_by_exten_locked (const struct ast_channel *chan, const char *exten, const char *context)
 Get next channel by exten (and optionally context) and lock it.
ast_channelast_walk_channel_by_name_prefix_locked (const struct ast_channel *chan, const char *name, const int namelen)
 Get channel by name prefix (locks channel).
int ast_write (struct ast_channel *chan, struct ast_frame *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)
 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 (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
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 107 of file channel.c.

Referenced by __ast_read().

#define AST_MIN_DTMF_DURATION   80

Minimum allowed digit length - 80ms

Definition at line 110 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 114 of file channel.c.

Referenced by __ast_read().

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

#define MONITOR_CONSTANT_DELAY

Definition at line 92 of file channel.c.

#define MONITOR_DELAY   150 * 8

Definition at line 93 of file channel.c.

Referenced by __ast_read(), and ast_write().

#define SPY_QUEUE_SAMPLE_LIMIT   4000

Definition at line 1539 of file channel.c.

Referenced by queue_frame_to_spies().

#define STATE2STR_BUFSIZE   32

Definition at line 103 of file channel.c.

Referenced by ast_state2str().


Enumeration Type Documentation

enum spy_direction

Enumerator:
SPY_READ 
SPY_WRITE 

Definition at line 1534 of file channel.c.

01534                    {
01535    SPY_READ,
01536    SPY_WRITE,
01537 };


Function Documentation

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

Definition at line 2100 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_lock, 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_CNG, 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_internal_timing_enabled(), 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_seekstream(), ast_set_flag, ast_setstate(), ast_settimeout(), 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, ast_frame::data, DEBUGCHAN_FLAG, ast_channel::dtmf_tv, ast_channel::dtmff, ast_channel::dtmfq, ast_channel::emulate_dtmf_digit, ast_channel::emulate_dtmf_duration, ast_channel_tech::exception, f, ast_channel::fdno, ast_channel::fds, ast_channel::fin, FRAMECOUNT_INC, ast_frame::frametype, func, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, ast_channel::insmpl, LOG_DEBUG, LOG_DTMF, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, MONITOR_DELAY, ast_channel::nativeformats, option_debug, ast_channel::outsmpl, queue_frame_to_spies(), ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readtrans, 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().

02101 {
02102    struct ast_frame *f = NULL;   /* the return value */
02103    int blah;
02104    int prestate;
02105 
02106    /* this function is very long so make sure there is only one return
02107     * point at the end (there is only one exception to this).
02108     */
02109    ast_channel_lock(chan);
02110    if (chan->masq) {
02111       if (ast_do_masquerade(chan))
02112          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02113       else
02114          f =  &ast_null_frame;
02115       goto done;
02116    }
02117 
02118    /* Stop if we're a zombie or need a soft hangup */
02119    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02120       if (chan->generator)
02121          ast_deactivate_generator(chan);
02122       goto done;
02123    }
02124    prestate = chan->_state;
02125 
02126    if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF | AST_FLAG_IN_DTMF) && 
02127        !ast_strlen_zero(chan->dtmfq) && 
02128       (ast_tvzero(chan->dtmf_tv) || ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) > AST_MIN_DTMF_GAP) ) {
02129       /* We have DTMF that has been deferred.  Return it now */
02130       chan->dtmff.subclass = chan->dtmfq[0];
02131       /* Drop first digit from the buffer */
02132       memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
02133       f = &chan->dtmff;
02134       if (ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY))
02135          chan->dtmff.frametype = AST_FRAME_DTMF_END;
02136       else {
02137          chan->dtmff.frametype = AST_FRAME_DTMF_BEGIN;
02138          ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02139          chan->emulate_dtmf_digit = f->subclass;
02140          chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
02141       }
02142       chan->dtmf_tv = ast_tvnow();
02143       goto done;
02144    }
02145    
02146    /* Read and ignore anything on the alertpipe, but read only
02147       one sizeof(blah) per frame that we send from it */
02148    if (chan->alertpipe[0] > -1)
02149       read(chan->alertpipe[0], &blah, sizeof(blah));
02150 
02151 #ifdef HAVE_ZAPTEL
02152    if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02153       int res;
02154 
02155       ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02156       blah = -1;
02157       /* IF we can't get event, assume it's an expired as-per the old interface */
02158       res = ioctl(chan->timingfd, ZT_GETEVENT, &blah);
02159       if (res)
02160          blah = ZT_EVENT_TIMER_EXPIRED;
02161 
02162       if (blah == ZT_EVENT_TIMER_PING) {
02163          if (AST_LIST_EMPTY(&chan->readq) || !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
02164             /* Acknowledge PONG unless we need it again */
02165             if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) {
02166                ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
02167             }
02168          }
02169       } else if (blah == ZT_EVENT_TIMER_EXPIRED) {
02170          ioctl(chan->timingfd, ZT_TIMERACK, &blah);
02171          if (chan->timingfunc) {
02172             /* save a copy of func/data before unlocking the channel */
02173             int (*func)(void *) = chan->timingfunc;
02174             void *data = chan->timingdata;
02175             ast_channel_unlock(chan);
02176             func(data);
02177          } else {
02178             blah = 0;
02179             ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
02180             chan->timingdata = NULL;
02181             ast_channel_unlock(chan);
02182          }
02183          /* cannot 'goto done' because the channel is already unlocked */
02184          return &ast_null_frame;
02185       } else
02186          ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
02187    } else
02188 #endif
02189    if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
02190       /* if the AST_GENERATOR_FD is set, call the generator with args
02191        * set to -1 so it can do whatever it needs to.
02192        */
02193       void *tmp = chan->generatordata;
02194       chan->generatordata = NULL;     /* reset to let ast_write get through */
02195       chan->generator->generate(chan, tmp, -1, -1);
02196       chan->generatordata = tmp;
02197       f = &ast_null_frame;
02198       goto done;
02199    }
02200 
02201    /* Check for pending read queue */
02202    if (!AST_LIST_EMPTY(&chan->readq)) {
02203       f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list);
02204       /* Interpret hangup and return NULL */
02205       /* XXX why not the same for frames from the channel ? */
02206       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
02207          ast_frfree(f);
02208          f = NULL;
02209       }
02210    } else {
02211       chan->blocker = pthread_self();
02212       if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02213          if (chan->tech->exception)
02214             f = chan->tech->exception(chan);
02215          else {
02216             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
02217             f = &ast_null_frame;
02218          }
02219          /* Clear the exception flag */
02220          ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02221       } else if (chan->tech->read)
02222          f = chan->tech->read(chan);
02223       else
02224          ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
02225    }
02226 
02227    if (f) {
02228       /* if the channel driver returned more than one frame, stuff the excess
02229          into the readq for the next ast_read call (note that we can safely assume
02230          that the readq is empty, because otherwise we would not have called into
02231          the channel driver and f would be only a single frame)
02232       */
02233       if (AST_LIST_NEXT(f, frame_list)) {
02234          AST_LIST_HEAD_SET_NOLOCK(&chan->readq, AST_LIST_NEXT(f, frame_list));
02235          AST_LIST_NEXT(f, frame_list) = NULL;
02236       }
02237 
02238       switch (f->frametype) {
02239       case AST_FRAME_CONTROL:
02240          if (f->subclass == AST_CONTROL_ANSWER) {
02241             if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02242                if (option_debug)
02243                   ast_log(LOG_DEBUG, "Ignoring answer on an inbound call!\n");
02244                ast_frfree(f);
02245                f = &ast_null_frame;
02246             } else if (prestate == AST_STATE_UP) {
02247                if (option_debug)
02248                   ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
02249                ast_frfree(f);
02250                f = &ast_null_frame;
02251             } else {
02252                /* Answer the CDR */
02253                ast_setstate(chan, AST_STATE_UP);
02254                if (!chan->cdr) { /* up till now, this insertion hasn't been done. Therefore,
02255                                to keep from throwing off the basic order of the universe,
02256                                we will try to keep this cdr from getting posted. */
02257                   chan->cdr = ast_cdr_alloc();
02258                   ast_cdr_init(chan->cdr, chan);
02259                   ast_cdr_start(chan->cdr);
02260                }
02261                
02262                ast_cdr_answer(chan->cdr);
02263             }
02264          }
02265          break;
02266       case AST_FRAME_DTMF_END:
02267          ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass, chan->name, f->len);
02268          /* Queue it up if DTMF is deffered, or if DTMF emulation is forced.
02269           * However, only let emulation be forced if the other end cares about BEGIN frames */
02270          if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF) ||
02271             (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) ) {
02272             if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
02273                chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
02274             else
02275                ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
02276             ast_frfree(f);
02277             f = &ast_null_frame;
02278          } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
02279             if (!ast_tvzero(chan->dtmf_tv) && 
02280                 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
02281                /* If it hasn't been long enough, defer this digit */
02282                if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
02283                   chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
02284                else
02285                   ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
02286                ast_frfree(f);
02287                f = &ast_null_frame;
02288             } else {
02289                /* There was no begin, turn this into a begin and send the end later */
02290                f->frametype = AST_FRAME_DTMF_BEGIN;
02291                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02292                chan->emulate_dtmf_digit = f->subclass;
02293                chan->dtmf_tv = ast_tvnow();
02294                if (f->len) {
02295                   if (f->len > AST_MIN_DTMF_DURATION)
02296                      chan->emulate_dtmf_duration = f->len;
02297                   else 
02298                      chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
02299                } else
02300                   chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
02301             }
02302          } else {
02303             struct timeval now = ast_tvnow();
02304             ast_clear_flag(chan, AST_FLAG_IN_DTMF);
02305             if (!f->len)
02306                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02307             if (f->len < AST_MIN_DTMF_DURATION) {
02308                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02309                chan->emulate_dtmf_digit = f->subclass;
02310                chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
02311                f = &ast_null_frame;
02312             } else
02313                chan->dtmf_tv = now;
02314          }
02315          break;
02316       case AST_FRAME_DTMF_BEGIN:
02317          ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name);
02318          if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY) || 
02319              (!ast_tvzero(chan->dtmf_tv) && 
02320                ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
02321             ast_frfree(f);
02322             f = &ast_null_frame;
02323          } else {
02324             ast_set_flag(chan, AST_FLAG_IN_DTMF);
02325             chan->dtmf_tv = ast_tvnow();
02326          }
02327          break;
02328       case AST_FRAME_NULL:
02329          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
02330             struct timeval now = ast_tvnow();
02331             if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
02332                chan->emulate_dtmf_duration = 0;
02333                ast_frfree(f);
02334                f = &chan->dtmff;
02335                f->frametype = AST_FRAME_DTMF_END;
02336                f->subclass = chan->emulate_dtmf_digit;
02337                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02338                chan->dtmf_tv = now;
02339                ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02340                chan->emulate_dtmf_digit = 0;
02341             }
02342          }
02343          break;
02344       case AST_FRAME_VOICE:
02345          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
02346           * is reached , because we want to make sure we pass at least one
02347           * voice frame through before starting the next digit, to ensure a gap
02348           * between DTMF digits. */
02349          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
02350             ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02351             chan->emulate_dtmf_digit = 0;
02352          }
02353 
02354          if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02355             ast_frfree(f);
02356             f = &ast_null_frame;
02357          } else if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
02358             struct timeval now = ast_tvnow();
02359             if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
02360                chan->emulate_dtmf_duration = 0;
02361                ast_frfree(f);
02362                f = &chan->dtmff;
02363                f->frametype = AST_FRAME_DTMF_END;
02364                f->subclass = chan->emulate_dtmf_digit;
02365                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02366                chan->dtmf_tv = now;
02367             } else {
02368                /* Drop voice frames while we're still in the middle of the digit */
02369                ast_frfree(f);
02370                f = &ast_null_frame;
02371             }
02372          } else if (!(f->subclass & chan->nativeformats)) {
02373             /* This frame can't be from the current native formats -- drop it on the
02374                floor */
02375             ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
02376                chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
02377             ast_frame_dump(chan->name, f, "<<");
02378             ast_frfree(f);
02379             f = &ast_null_frame;
02380          } else {
02381             if (chan->spies)
02382                queue_frame_to_spies(chan, f, SPY_READ);
02383             
02384             if (chan->monitor && chan->monitor->read_stream ) {
02385                /* XXX what does this do ? */
02386 #ifndef MONITOR_CONSTANT_DELAY
02387                int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
02388                if (jump >= 0) {
02389                   jump = chan->outsmpl - chan->insmpl;
02390                   if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
02391                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
02392                   chan->insmpl += jump + f->samples;
02393                } else
02394                   chan->insmpl+= f->samples;
02395 #else
02396                int jump = chan->outsmpl - chan->insmpl;
02397                if (jump - MONITOR_DELAY >= 0) {
02398                   if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02399                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
02400                   chan->insmpl += jump;
02401                } else
02402                   chan->insmpl += f->samples;
02403 #endif
02404                if (chan->monitor->state == AST_MONITOR_RUNNING) {
02405                   if (ast_writestream(chan->monitor->read_stream, f) < 0)
02406                      ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
02407                }
02408             }
02409 
02410             if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL)
02411                f = &ast_null_frame;
02412 
02413             /* Run generator sitting on the line if timing device not available
02414             * and synchronous generation of outgoing frames is necessary       */
02415             if (chan->generatordata &&  !ast_internal_timing_enabled(chan)) {
02416                void *tmp = chan->generatordata;
02417                int res;
02418 
02419                if (chan->timingfunc) {
02420                   if (option_debug > 1)
02421                      ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
02422                   ast_settimeout(chan, 0, NULL, NULL);
02423                }
02424 
02425                chan->generatordata = NULL;   /* reset, to let writes go through */
02426                res = chan->generator->generate(chan, tmp, f->datalen, f->samples);
02427                chan->generatordata = tmp;
02428                if (res) {
02429                   if (option_debug > 1)
02430                      ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
02431                   ast_deactivate_generator(chan);
02432                }
02433 
02434             } else if (f->frametype == AST_FRAME_CNG) {
02435                if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
02436                   if (option_debug > 1)
02437                      ast_log(LOG_DEBUG, "Generator got CNG, switching to timed mode\n");
02438                   ast_settimeout(chan, 160, generator_force, chan);
02439                }
02440             }
02441          }
02442       default:
02443          /* Just pass it on! */
02444          break;
02445       }
02446    } else {
02447       /* Make sure we always return NULL in the future */
02448       chan->_softhangup |= AST_SOFTHANGUP_DEV;
02449       if (chan->generator)
02450          ast_deactivate_generator(chan);
02451       /* End the CDR if appropriate */
02452       if (chan->cdr)
02453          ast_cdr_end(chan->cdr);
02454    }
02455 
02456    /* High bit prints debugging */
02457    if (chan->fin & DEBUGCHAN_FLAG)
02458       ast_frame_dump(chan->name, f, "<<");
02459    chan->fin = FRAMECOUNT_INC(chan->fin);
02460 
02461 done:
02462    ast_channel_unlock(chan);
02463    return f;
02464 }

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

Definition at line 2961 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(), ast_set_callerid(), ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), ast_channel::cdr, outgoing_helper::cid_name, outgoing_helper::cid_num, outgoing_helper::context, ast_channel::context, outgoing_helper::exten, ast_channel::exten, f, ast_channel::hangupcause, LOG_NOTICE, outgoing_helper::parent_channel, outgoing_helper::priority, ast_channel::priority, and outgoing_helper::vars.

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

02962 {
02963    int dummy_outstate;
02964    int cause = 0;
02965    struct ast_channel *chan;
02966    int res = 0;
02967    
02968    if (outstate)
02969       *outstate = 0;
02970    else
02971       outstate = &dummy_outstate;   /* make outstate always a valid pointer */
02972 
02973    chan = ast_request(type, format, data, &cause);
02974    if (!chan) {
02975       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
02976       /* compute error and return */
02977       if (cause == AST_CAUSE_BUSY)
02978          *outstate = AST_CONTROL_BUSY;
02979       else if (cause == AST_CAUSE_CONGESTION)
02980          *outstate = AST_CONTROL_CONGESTION;
02981       return NULL;
02982    }
02983 
02984    if (oh) {
02985       if (oh->vars)  
02986          ast_set_variables(chan, oh->vars);
02987       /* XXX why is this necessary, for the parent_channel perhaps ? */
02988       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
02989          ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
02990       if (oh->parent_channel)
02991          ast_channel_inherit_variables(oh->parent_channel, chan);
02992       if (oh->account)
02993          ast_cdr_setaccount(chan, oh->account); 
02994    }
02995    ast_set_callerid(chan, cid_num, cid_name, cid_num);
02996 
02997    
02998 
02999    if (!chan->cdr) { /* up till now, this insertion hasn't been done. Therefore,
03000             to keep from throwing off the basic order of the universe,
03001             we will try to keep this cdr from getting posted. */
03002       chan->cdr = ast_cdr_alloc();
03003       ast_cdr_init(chan->cdr, chan);
03004       ast_cdr_start(chan->cdr);
03005    }
03006    if (ast_call(chan, data, 0)) {   /* ast_call failed... */
03007       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
03008    } else {
03009       res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
03010       while (timeout && chan->_state != AST_STATE_UP) {
03011          struct ast_frame *f;
03012          res = ast_waitfor(chan, timeout);
03013          if (res <= 0) /* error, timeout, or done */
03014             break;
03015          if (timeout > -1)
03016             timeout = res;
03017          f = ast_read(chan);
03018          if (!f) {
03019             *outstate = AST_CONTROL_HANGUP;
03020             res = 0;
03021             break;
03022          }
03023          if (f->frametype == AST_FRAME_CONTROL) {
03024             switch (f->subclass) {
03025             case AST_CONTROL_RINGING:  /* record but keep going */
03026                *outstate = f->subclass;
03027                break;
03028 
03029             case AST_CONTROL_BUSY:
03030             case AST_CONTROL_CONGESTION:
03031             case AST_CONTROL_ANSWER:
03032                *outstate = f->subclass;
03033                timeout = 0;      /* trick to force exit from the while() */
03034                break;
03035 
03036             /* Ignore these */
03037             case AST_CONTROL_PROGRESS:
03038             case AST_CONTROL_PROCEEDING:
03039             case AST_CONTROL_HOLD:
03040             case AST_CONTROL_UNHOLD:
03041             case AST_CONTROL_VIDUPDATE:
03042             case -1:       /* Ignore -- just stopping indications */
03043                break;
03044 
03045             default:
03046                ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
03047             }
03048          }
03049          ast_frfree(f);
03050       }
03051    }
03052 
03053    /* Final fixups */
03054    if (oh) {
03055       if (!ast_strlen_zero(oh->context))
03056          ast_copy_string(chan->context, oh->context, sizeof(chan->context));
03057       if (!ast_strlen_zero(oh->exten))
03058          ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
03059       if (oh->priority) 
03060          chan->priority = oh->priority;
03061    }
03062    if (chan->_state == AST_STATE_UP)
03063       *outstate = AST_CONTROL_ANSWER;
03064 
03065    if (res <= 0) {
03066       if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
03067          ast_cdr_init(chan->cdr, chan);
03068       if (chan->cdr) {
03069          char tmp[256];
03070          snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
03071          ast_cdr_setapp(chan->cdr,"Dial",tmp);
03072          ast_cdr_update(chan);
03073          ast_cdr_start(chan->cdr);
03074          ast_cdr_end(chan->cdr);
03075          /* If the cause wasn't handled properly */
03076          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
03077             ast_cdr_failed(chan->cdr);
03078       }
03079       ast_hangup(chan);
03080       chan = NULL;
03081    }
03082    return chan;
03083 }

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

Activate a given generator

Definition at line 1817 of file channel.c.

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

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

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

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns number of active/allocated channels

Definition at line 454 of file channel.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.

Referenced by quit_handler().

00455 {
00456    struct ast_channel *c;
00457    int cnt = 0;
00458    AST_LIST_LOCK(&channels);
00459    AST_LIST_TRAVERSE(&channels, c, chan_list)
00460       cnt++;
00461    AST_LIST_UNLOCK(&channels);
00462    return cnt;
00463 }

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 1750 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, and ast_channel::tech.

Referenced by __login_exec(), agi_exec_full(), alarmreceiver_exec(), app_exec(), ast_bridge_call(), ast_control_streamfile(), ast_pickup_call(), auth_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(), mwanalyze_exec(), nv_background_detect_exec(), nv_detectfax_exec(), park_call_exec(), park_exec(), pbx_builtin_answer(), pbx_builtin_background(), pickup_do(), playback_exec(), privacy_exec(), read_exec(), rpt_exec(), run_station(), rxfax_exec(), sayunixtime_exec(), send_waveform_to_channel(), skel_exec(), sla_handle_dial_state_event(), sla_station_exec(), speech_background(), testclient_exec(), testserver_exec(), txfax_exec(), vm_exec(), vm_execmain(), waitforsilence_exec(), zapateller_exec(), and zapras_exec().

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

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

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

Referenced by quit_handler().

00442 {
00443    struct ast_channel *c;
00444    shutting_down = 1;
00445    if (hangup) {
00446       AST_LIST_LOCK(&channels);
00447       AST_LIST_TRAVERSE(&channels, c, chan_list)
00448          ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00449       AST_LIST_UNLOCK(&channels);
00450    }
00451 }

int ast_best_codec ( int  fmts  ) 

Pick the best audio codec.

Pick the best codec

G.722 is better then all codecs in this list

alaw used by all telephone equipment at Russia

Okay, well, signed linear is easy to translate into other stuff! slinear<->alaw recoding very fast

ulaw standart for USA and Japan

Speex is free, but computationally more expensive than GSM

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

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

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

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

Definition at line 666 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_channel_best_codec(), 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().

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

struct ast_channel* ast_bridged_channel ( struct ast_channel chan  ) 

Find bridged channel.

Parameters:
chan Current channel

Definition at line 3782 of file channel.c.

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

Referenced by __zt_exception(), agents_show(), agents_show_online(), ast_channel_masquerade(), attempt_transfer(), check_bridge(), common_exec(), console_transfer(), console_transfer_deprecated(), create_jb(), export_aoc_vars(), handle_chanlist(), handle_chanlist_deprecated(), handle_hd_hf(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response_invite(), handle_showchan(), handle_showchan_deprecated(), local_attended_transfer(), mgcp_hangup(), mgcp_ss(), misdn_transfer_bc(), mixmonitor_thread(), schedule_delivery(), sip_read(), socket_process(), ss_thread(), start_spying(), startmon(), zt_handle_event(), and zt_hangup().

03783 {
03784    struct ast_channel *bridged;
03785    bridged = chan->_bridge;
03786    if (bridged && bridged->tech->bridged_channel)
03787       bridged = bridged->tech->bridged_channel(chan, bridged);
03788    return bridged;
03789 }

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 3139 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(), features_call(), findmeexec(), function_ilink(), ring_entry(), rpt(), rpt_exec(), and wait_for_answer().

03140 {
03141    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
03142       If the remote end does not answer within the timeout, then do NOT hang up, but
03143       return anyway.  */
03144    int res = -1;
03145    /* Stop if we're a zombie or need a soft hangup */
03146    ast_channel_lock(chan);
03147    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03148       if (chan->tech->call)
03149          res = chan->tech->call(chan, addr, timeout);
03150       ast_set_flag(chan, AST_FLAG_OUTGOING);
03151    }
03152    ast_channel_unlock(chan);
03153    return res;
03154 }

void ast_cancel_shutdown ( void   ) 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 466 of file channel.c.

References shutting_down.

Referenced by handle_abort_halt().

00467 {
00468    shutting_down = 0;
00469 }

const char* ast_cause2str ( int  state  ) 

Gives the string form of a given hangup cause.

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

Definition at line 586 of file channel.c.

References causes, and desc.

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

00587 {
00588    int x;
00589 
00590    for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++) {
00591       if (causes[x].cause == cause)
00592          return causes[x].desc;
00593    }
00594 
00595    return "Unknown";
00596 }

void ast_change_name ( struct ast_channel chan,
char *  newname 
)

Change channel name.

Definition at line 3366 of file channel.c.

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

03367 {
03368    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
03369    ast_string_field_set(chan, name, newname);
03370 }

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

Create a channel structure.

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

Definition at line 720 of file channel.c.

References ast_calloc, ast_log(), AST_MAX_FDS, ast_string_field_init, ast_channel::flags, free, HAVE_ZAPTEL, LOG_WARNING, sched_context_create(), and shutting_down.

Referenced by __oh323_new(), agent_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_masq_park_call(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), 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().

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

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 3971 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_test_flag, ast_tvadd(), ast_tvsub(), ast_verbose(), ast_channel_tech::bridge, bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, config, EVENT_FLAG_CALL, ast_channel::generator, LOG_DEBUG, LOG_WARNING, manager_event(), ast_channel::monitor, ast_channel::nativeformats, option_verbose, ast_channel::readformat, ast_channel_tech::send_digit_begin, ast_channel::spies, t, ast_channel::tech, VERBOSE_PREFIX_3, and ast_channel::writeformat.

Referenced by ast_bridge_call().

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

int ast_channel_cmpwhentohangup ( struct ast_channel chan,
time_t  offset 
)

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

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

Definition at line 486 of file channel.c.

References ast_channel::whentohangup.

00487 {
00488    time_t whentohangup;
00489 
00490    if (chan->whentohangup == 0) {
00491       return (offset == 0) ? 0 : -1;
00492    } else {
00493       if (offset == 0)  /* XXX why is this special ? */
00494          return (1);
00495       else {
00496          whentohangup = offset + time (NULL);
00497          if (chan->whentohangup < whentohangup)
00498             return (1);
00499          else if (chan->whentohangup == whentohangup)
00500             return (0);
00501          else
00502             return (-1);
00503       }
00504    }
00505 }

int ast_channel_datastore_add ( struct ast_channel chan,
struct ast_datastore datastore 
)

Add a datastore to a channel.

Definition at line 1281 of file channel.c.

References AST_LIST_INSERT_HEAD.

Referenced by speech_create().

01282 {
01283    int res = 0;
01284 
01285    AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
01286 
01287    return res;
01288 }

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

Create a channel datastore structure.

Definition at line 1237 of file channel.c.

References ast_calloc, ast_strdup, and ast_datastore::info.

Referenced by speech_create().

01238 {
01239    struct ast_datastore *datastore = NULL;
01240 
01241    /* Make sure we at least have type so we can identify this */
01242    if (info == NULL) {
01243       return NULL;
01244    }
01245 
01246    /* Allocate memory for datastore and clear it */
01247    datastore = ast_calloc(1, sizeof(*datastore));
01248    if (datastore == NULL) {
01249       return NULL;
01250    }
01251 
01252    datastore->info = info;
01253 
01254    datastore->uid = ast_strdup(uid);
01255 
01256    return datastore;
01257 }

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

Find a datastore on a channel.

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

01309 {
01310    struct ast_datastore *datastore = NULL;
01311    
01312    if (info == NULL)
01313       return NULL;
01314 
01315    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
01316       if (datastore->info == info) {
01317          if (uid != NULL && datastore->uid != NULL) {
01318             if (!strcasecmp(uid, datastore->uid)) {
01319                /* Matched by type AND uid */
01320                break;
01321             }
01322          } else {
01323             /* Matched by type at least */
01324             break;
01325          }
01326       }
01327    }
01328    AST_LIST_TRAVERSE_SAFE_END
01329 
01330    return datastore;
01331 }

int ast_channel_datastore_free ( struct ast_datastore datastore  ) 

Free a channel datastore structure.

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

01260 {
01261    int res = 0;
01262 
01263    /* Using the destroy function (if present) destroy the data */
01264    if (datastore->info->destroy != NULL && datastore->data != NULL) {
01265       datastore->info->destroy(datastore->data);
01266       datastore->data = NULL;
01267    }
01268 
01269    /* Free allocated UID memory */
01270    if (datastore->uid != NULL) {
01271       free(datastore->uid);
01272       datastore->uid = NULL;
01273    }
01274 
01275    /* Finally free memory used by ourselves */
01276    free(datastore);
01277 
01278    return res;
01279 }

int ast_channel_datastore_remove ( struct ast_channel chan,
struct ast_datastore datastore 
)

Remove a datastore from a channel.

Definition at line 1290 of file channel.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, and AST_LIST_TRAVERSE_SAFE_END.

Referenced by speech_background(), and speech_destroy().

01291 {
01292    struct ast_datastore *datastore2 = NULL;
01293    int res = -1;
01294 
01295    /* Find our position and remove ourselves */
01296    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, entry) {
01297       if (datastore2 == datastore) {
01298          AST_LIST_REMOVE_CURRENT(&chan->datastores, entry);
01299          res = 0;
01300          break;
01301       }
01302    }
01303    AST_LIST_TRAVERSE_SAFE_END
01304 
01305    return res;
01306 }

int ast_channel_defer_dtmf ( struct ast_channel chan  ) 

Set defer DTMF flag on channel.

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

Definition at line 974 of file channel.c.

References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.

Referenced by __adsi_transmit_messages(), and find_cache().

00975 {
00976    int pre = 0;
00977 
00978    if (chan) {
00979       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
00980       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
00981    }
00982    return pre;
00983 }

void ast_channel_free ( struct ast_channel chan  ) 

Free a channel structure.

Definition at line 1155 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_pools, ast_translator_free_path(), ast_var_delete(), ast_channel::cid, f, free, free_cid(), ast_channel::lock, 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 agent_cleanup(), agent_new(), ast_hangup(), ast_pbx_outgoing_cdr_failed(), local_new(), make_email_file(), pbx_substitute_variables_helper_full(), and sendpage().

01156 {
01157    int fd;
01158    struct ast_var_t *vardata;
01159    struct ast_frame *f;
01160    struct varshead *headp;
01161    struct ast_datastore *datastore = NULL;
01162    char name[AST_CHANNEL_NAME];
01163    
01164    headp=&chan->varshead;
01165    
01166    AST_LIST_LOCK(&channels);
01167    AST_LIST_REMOVE(&channels, chan, chan_list);
01168    /* Lock and unlock the channel just to be sure nobody
01169       has it locked still */
01170    ast_channel_lock(chan);
01171    ast_channel_unlock(chan);
01172    if (chan->tech_pvt) {
01173       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
01174       free(chan->tech_pvt);
01175    }
01176 
01177    if (chan->sched)
01178       sched_context_destroy(chan->sched);
01179 
01180    ast_copy_string(name, chan->name, sizeof(name));
01181 
01182    /* Stop monitoring */
01183    if (chan->monitor)
01184       chan->monitor->stop( chan, 0 );
01185 
01186    /* If there is native format music-on-hold state, free it */
01187    if (chan->music_state)
01188       ast_moh_cleanup(chan);
01189 
01190    /* if someone is whispering on the channel, stop them */
01191    if (chan->whisper)
01192       ast_channel_whisper_stop(chan);
01193 
01194    /* Free translators */
01195    if (chan->readtrans)
01196       ast_translator_free_path(chan->readtrans);
01197    if (chan->writetrans)
01198       ast_translator_free_path(chan->writetrans);
01199    if (chan->pbx)
01200       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
01201    free_cid(&chan->cid);
01202    ast_mutex_destroy(&chan->lock);
01203    /* Close pipes if appropriate */
01204    if ((fd = chan->alertpipe[0]) > -1)
01205       close(fd);
01206    if ((fd = chan->alertpipe[1]) > -1)
01207       close(fd);
01208    if ((fd = chan->timingfd) > -1)
01209       close(fd);
01210    while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
01211       ast_frfree(f);
01212    
01213    /* Get rid of each of the data stores on the channel */
01214    while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
01215       /* Free the data store */
01216       ast_channel_datastore_free(datastore);
01217    AST_LIST_HEAD_INIT_NOLOCK(&chan->datastores);
01218 
01219    /* loop over the variables list, freeing all data and deleting list items */
01220    /* no need to lock the list, as the channel is already locked */
01221    
01222    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
01223       ast_var_delete(vardata);
01224 
01225    ast_app_group_discard(chan);
01226 
01227    /* Destroy the jitterbuffer */
01228    ast_jb_destroy(chan);
01229 
01230    ast_string_field_free_pools(chan);
01231    free(chan);
01232    AST_LIST_UNLOCK(&channels);
01233 
01234    ast_device_state_changed_literal(name);
01235 }

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

03373 {
03374    struct ast_var_t *current, *newvar;
03375    const char *varname;
03376 
03377    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
03378       int vartype = 0;
03379 
03380       varname = ast_var_full_name(current);
03381       if (!varname)
03382          continue;
03383 
03384       if (varname[0] == '_') {
03385          vartype = 1;
03386          if (varname[1] == '_')
03387             vartype = 2;
03388       }
03389 
03390       switch (vartype) {
03391       case 1:
03392          newvar = ast_var_assign(&varname[1], ast_var_value(current));
03393          if (newvar) {
03394             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03395             if (option_debug)
03396                ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
03397          }
03398          break;
03399       case 2:
03400          newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
03401          if (newvar) {
03402             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03403             if (option_debug)
03404                ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
03405          }
03406          break;
03407       default:
03408          if (option_debug)
03409             ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
03410          break;
03411       }
03412    }
03413 }

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 3246 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, and ast_channel::nativeformats.

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

03247 {
03248    int src;
03249    int dst;
03250 
03251    /* Set up translation from the chan to the peer */
03252    src = chan->nativeformats;
03253    dst = peer->nativeformats;
03254    if (ast_translator_best_choice(&dst, &src) < 0) {
03255       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
03256       return -1;
03257    }
03258 
03259    /* if the best path is not 'pass through', then
03260       transcoding is needed; if desired, force transcode path
03261       to use SLINEAR between channels, but only if there is
03262       no direct conversion available */
03263    if ((src != dst) && ast_opt_transcode_via_slin &&
03264        (ast_translate_path_steps(dst, src) != 1))
03265       dst = AST_FORMAT_SLINEAR;
03266    if (ast_set_read_format(chan, dst) < 0) {
03267       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
03268       return -1;
03269    }
03270    if (ast_set_write_format(peer, dst) < 0) {
03271       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst);
03272       return -1;
03273    }
03274 
03275    /* Set up translation from the peer to the chan */
03276    src = peer->nativeformats;
03277    dst = chan->nativeformats;
03278    if (ast_translator_best_choice(&dst, &src) < 0) {
03279       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst);
03280       return -1;
03281    }
03282 
03283    /* if the best path is not 'pass through', then
03284       transcoding is needed; if desired, force transcode path
03285       to use SLINEAR between channels, but only if there is
03286       no direct conversion available */
03287    if ((src != dst) && ast_opt_transcode_via_slin &&
03288        (ast_translate_path_steps(dst, src) != 1))
03289       dst = AST_FORMAT_SLINEAR;
03290    if (ast_set_read_format(peer, dst) < 0) {
03291       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst);
03292       return -1;
03293    }
03294    if (ast_set_write_format(chan, dst) < 0) {
03295       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst);
03296       return -1;
03297    }
03298    return 0;
03299 }

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 3301 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(), LOG_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, and option_debug.

Referenced by ast_async_goto(), 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(), pickup_do(), and sip_park().

03302 {
03303    int res = -1;
03304    struct ast_channel *final_orig = original, *final_clone = clone;
03305 
03306    ast_channel_lock(original);
03307    while (ast_channel_trylock(clone)) {
03308       ast_channel_unlock(original);
03309       usleep(1);
03310       ast_channel_lock(original);
03311    }
03312 
03313    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
03314       and if so, we don't really want to masquerade it, but its proxy */
03315    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
03316       final_orig = original->_bridge;
03317 
03318    if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone))
03319       final_clone = clone->_bridge;
03320 
03321    if ((final_orig != original) || (final_clone != clone)) {
03322       ast_channel_lock(final_orig);
03323       while (ast_channel_trylock(final_clone)) {
03324          ast_channel_unlock(final_orig);
03325          usleep(1);
03326          ast_channel_lock(final_orig);
03327       }
03328       ast_channel_unlock(clone);
03329       ast_channel_unlock(original);
03330       original = final_orig;
03331       clone = final_clone;
03332    }
03333 
03334    if (original == clone) {
03335       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
03336       ast_channel_unlock(clone);
03337       ast_channel_unlock(original);
03338       return -1;
03339    }
03340 
03341    if (option_debug)
03342       ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
03343          clone->name, original->name);
03344    if (original->masq) {
03345       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03346          original->masq->name, original->name);
03347    } else if (clone->masqr) {
03348       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03349          clone->name, clone->masqr->name);
03350    } else {
03351       original->masq = clone;
03352       clone->masqr = original;
03353       ast_queue_frame(original, &ast_null_frame);
03354       ast_queue_frame(clone, &ast_null_frame);
03355       if (option_debug)
03356          ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
03357       res = 0;
03358    }
03359 
03360    ast_channel_unlock(clone);
03361    ast_channel_unlock(original);
03362 
03363    return res;
03364 }

int ast_channel_register ( const struct ast_channel_tech tech  ) 

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

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

Definition at line 508 of file channel.c.

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

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

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

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

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

03235 {
03236    if (chan->tech->send_html)
03237       return chan->tech->send_html(chan, subclass, data, datalen);
03238    return -1;
03239 }

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

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

Definition at line 3241 of file channel.c.

References ast_channel_sendhtml(), and AST_HTML_URL.

Referenced by sendurl_exec(), and try_calling().

03242 {
03243    return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
03244 }

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

Sets an option on a channel.

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

Definition at line 4224 of file channel.c.

References ast_log(), 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(), set_listen_volume(), set_talk_volume(), set_volume(), try_calling(), vm_forwardoptions(), and zt_hangup().

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

void ast_channel_setwhentohangup ( struct ast_channel chan,
time_t  offset 
)

Set when to hang a channel up.

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

Definition at line 478 of file channel.c.

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

Referenced by action_timeout(), and timeout_write().

00479 {
00480    chan->whentohangup = offset ? time(NULL) + offset : 0;
00481    ast_queue_frame(chan, &ast_null_frame);
00482    return;
00483 }

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

01334 {
01335    /* Link the owner channel to the spy */
01336    spy->chan = chan;
01337 
01338    if (!ast_test_flag(spy, CHANSPY_FORMAT_AUDIO)) {
01339       ast_log(LOG_WARNING, "Could not add channel spy '%s' to channel '%s', only audio format spies are supported.\n",
01340          spy->type, chan->name);
01341       return -1;
01342    }
01343 
01344    if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST) && (spy->read_queue.format != AST_FORMAT_SLINEAR)) {
01345       ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n",
01346          ast_getformatname(spy->read_queue.format));
01347       return -1;
01348    }
01349 
01350    if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST) && (spy->write_queue.format != AST_FORMAT_SLINEAR)) {
01351       ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n",
01352          ast_getformatname(spy->write_queue.format));
01353       return -1;
01354    }
01355 
01356    if (ast_test_flag(spy, CHANSPY_MIXAUDIO) &&
01357        ((spy->read_queue.format != AST_FORMAT_SLINEAR) ||
01358         (spy->write_queue.format != AST_FORMAT_SLINEAR))) {
01359       ast_log(LOG_WARNING, "Cannot provide audio mixing on '%s'-'%s' format spies\n",
01360          ast_getformatname(spy->read_queue.format), ast_getformatname(spy->write_queue.format));
01361       return -1;
01362    }
01363 
01364    if (!chan->spies) {
01365       if (!(chan->spies = ast_calloc(1, sizeof(*chan->spies)))) {
01366          return -1;
01367       }
01368 
01369       AST_LIST_HEAD_INIT_NOLOCK(&chan->spies->list);
01370       AST_LIST_INSERT_HEAD(&chan->spies->list, spy, list);
01371    } else {
01372       AST_LIST_INSERT_TAIL(&chan->spies->list, spy, list);
01373    }
01374 
01375    if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) {
01376       ast_cond_init(&spy->trigger, NULL);
01377       ast_set_flag(spy, CHANSPY_TRIGGER_READ);
01378       ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE);
01379    }
01380 
01381    if (option_debug)
01382       ast_log(LOG_DEBUG, "Spy %s added to channel %s\n",
01383          spy->type, chan->name);
01384 
01385    return 0;
01386 }

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

01469 {
01470    struct ast_frame *f = NULL;
01471 
01472    if (spy->status == CHANSPY_DONE)
01473       return;
01474 
01475    /* Switch status to done in case we get called twice */
01476    spy->status = CHANSPY_DONE;
01477 
01478    /* Drop any frames in the queue */
01479    while ((f = AST_LIST_REMOVE_HEAD(&spy->write_queue.list, frame_list)))
01480       ast_frfree(f);
01481    while ((f = AST_LIST_REMOVE_HEAD(&spy->read_queue.list, frame_list)))
01482       ast_frfree(f);
01483 
01484    /* Destroy the condition if in use */
01485    if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
01486       ast_cond_destroy(&spy->trigger);
01487 
01488    /* Destroy our mutex since it is no longer in use */
01489    ast_mutex_destroy(&spy->lock);
01490 
01491    return;
01492 }

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

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 4540 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, result, ast_channel_spy_queue::samples, ast_channel_spy::write_queue, and ast_channel_spy::write_vol_adjustment.

Referenced by mixmonitor_thread(), and spy_generate().

04541 {
04542    struct ast_frame *result;
04543    /* buffers are allocated to hold SLINEAR, which is the largest format */
04544         short read_buf[samples];
04545         short write_buf[samples];
04546    struct ast_frame *read_frame;
04547    struct ast_frame *write_frame;
04548    int need_dup;
04549    struct ast_frame stack_read_frame = { .frametype = AST_FRAME_VOICE,
04550                      .subclass = spy->read_queue.format,
04551                      .data = read_buf,
04552                      .samples = samples,
04553                      .datalen = ast_codec_get_len(spy->read_queue.format, samples),
04554    };
04555    struct ast_frame stack_write_frame = { .frametype = AST_FRAME_VOICE,
04556                       .subclass = spy->write_queue.format,
04557                       .data = write_buf,
04558                       .samples = samples,
04559                       .datalen = ast_codec_get_len(spy->write_queue.format, samples),
04560    };
04561 
04562    /* if a flush has been requested, dump everything in whichever queue is larger */
04563    if (ast_test_flag(spy, CHANSPY_TRIGGER_FLUSH)) {
04564       if (spy->read_queue.samples > spy->write_queue.samples) {
04565          if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST)) {
04566             AST_LIST_TRAVERSE(&spy->read_queue.list, result, frame_list)
04567                ast_frame_adjust_volume(result, spy->read_vol_adjustment);
04568          }
04569          result = AST_LIST_FIRST(&spy->read_queue.list);
04570          AST_LIST_HEAD_SET_NOLOCK(&spy->read_queue.list, NULL);
04571          spy->read_queue.samples = 0;
04572       } else {
04573          if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) {
04574             AST_LIST_TRAVERSE(&spy->write_queue.list, result, frame_list)
04575                ast_frame_adjust_volume(result, spy->write_vol_adjustment);
04576          }
04577          result = AST_LIST_FIRST(&spy->write_queue.list);
04578          AST_LIST_HEAD_SET_NOLOCK(&spy->write_queue.list, NULL);
04579          spy->write_queue.samples = 0;
04580       }
04581       ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
04582       return result;
04583    }
04584 
04585    if ((spy->read_queue.samples < samples) || (spy->write_queue.samples < samples))
04586       return NULL;
04587 
04588    /* short-circuit if both head frames have exactly what we want */
04589    if ((AST_LIST_FIRST(&spy->read_queue.list)->samples == samples) &&
04590        (AST_LIST_FIRST(&spy->write_queue.list)->samples == samples)) {
04591       read_frame = AST_LIST_REMOVE_HEAD(&spy->read_queue.list, frame_list);
04592       write_frame = AST_LIST_REMOVE_HEAD(&spy->write_queue.list, frame_list);
04593 
04594       spy->read_queue.samples -= samples;
04595       spy->write_queue.samples -= samples;
04596 
04597       need_dup = 0;
04598    } else {
04599       copy_data_from_queue(&spy->read_queue, read_buf, samples);
04600       copy_data_from_queue(&spy->write_queue, write_buf, samples);
04601 
04602       read_frame = &stack_read_frame;
04603       write_frame = &stack_write_frame;
04604       need_dup = 1;
04605    }
04606    
04607    if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST))
04608       ast_frame_adjust_volume(read_frame, spy->read_vol_adjustment);
04609 
04610    if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST))
04611       ast_frame_adjust_volume(write_frame, spy->write_vol_adjustment);
04612 
04613    if (ast_test_flag(spy, CHANSPY_MIXAUDIO)) {
04614       ast_frame_slinear_sum(read_frame, write_frame);
04615 
04616       if (need_dup)
04617          result = ast_frdup(read_frame);
04618       else {
04619          result = read_frame;
04620          ast_frfree(write_frame);
04621       }
04622    } else {
04623       if (need_dup) {
04624          result = ast_frdup(read_frame);
04625          AST_LIST_NEXT(result, frame_list) = ast_frdup(write_frame);
04626       } else {
04627          result = read_frame;
04628          AST_LIST_NEXT(result, frame_list) = write_frame;
04629       }
04630    }
04631 
04632    return result;
04633 }

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

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

Referenced by channel_spy().

01459 {
01460    if (!chan->spies)
01461       return;
01462 
01463    AST_LIST_REMOVE(&chan->spies->list, spy, list);
01464    spy_detach(spy, chan);
01465    spy_cleanup(chan);
01466 }

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

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

Referenced by mixmonitor_cli(), and stop_mixmonitor_exec().

01427 {
01428    struct ast_channel_spy *spy = NULL;
01429    
01430    if (!chan->spies)
01431       return;
01432 
01433    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) {
01434       ast_mutex_lock(&spy->lock);
01435       if ((spy->type == type) && (spy->status == CHANSPY_RUNNING)) {
01436          ast_mutex_unlock(&spy->lock);
01437          AST_LIST_REMOVE_CURRENT(&chan->spies->list, list);
01438          spy_detach(spy, chan);
01439       } else
01440          ast_mutex_unlock(&spy->lock);
01441    }
01442    AST_LIST_TRAVERSE_SAFE_END
01443    spy_cleanup(chan);
01444 }

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

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

Referenced by mixmonitor_thread().

01447 {
01448    struct timeval tv;
01449    struct timespec ts;
01450 
01451    tv = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000));
01452    ts.tv_sec = tv.tv_sec;
01453    ts.tv_nsec = tv.tv_usec * 1000;
01454 
01455    ast_cond_timedwait(&spy->trigger, &spy->lock, &ts);
01456 }

struct ast_silence_generator* ast_channel_start_silence_generator ( struct ast_channel chan  ) 

Starts a silence generator on the given channel.

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

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

Definition at line 4672 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, silence_generator, and ast_channel::writeformat.

Referenced by __ast_play_and_record(), and channel_spy().

04673 {
04674    struct ast_silence_generator *state;
04675 
04676    if (!(state = ast_calloc(1, sizeof(*state)))) {
04677       return NULL;
04678    }
04679 
04680    state->old_write_format = chan->writeformat;
04681 
04682    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
04683       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
04684       free(state);
04685       return NULL;
04686    }
04687 
04688    ast_activate_generator(chan, &silence_generator, state);
04689 
04690    if (option_debug)
04691       ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
04692 
04693    return state;
04694 }

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

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

Referenced by __ast_play_and_record(), and channel_spy().

04697 {
04698    if (!state)
04699       return;
04700 
04701    ast_deactivate_generator(chan);
04702 
04703    if (option_debug)
04704       ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
04705 
04706    if (ast_set_write_format(chan, state->old_write_format) < 0)
04707       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
04708 
04709    free(state);
04710 }

int ast_channel_supports_html ( struct ast_channel channel  ) 

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

Definition at line 3229 of file channel.c.

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

Referenced by sendurl_exec(), and try_calling().

03230 {
03231    return (chan->tech->send_html) ? 1 : 0;
03232 }

void ast_channel_undefer_dtmf ( struct ast_channel chan  ) 

Unset defer DTMF flag on channel.

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

Definition at line 986 of file channel.c.

References ast_clear_flag, and AST_FLAG_DEFER_DTMF.

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

00987 {
00988    if (chan)
00989       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
00990 }

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

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

Referenced by __unload_module(), and unload_module().

00541 {
00542    struct chanlist *chan;
00543 
00544    if (option_debug)
00545       ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
00546 
00547    AST_LIST_LOCK(&channels);
00548 
00549    AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00550       if (chan->tech == tech) {
00551          AST_LIST_REMOVE_CURRENT(&backends, list);
00552          free(chan);
00553          if (option_verbose > 1)
00554             ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
00555          break;   
00556       }
00557    }
00558    AST_LIST_TRAVERSE_SAFE_END
00559 
00560    AST_LIST_UNLOCK(&channels);
00561 }

struct ast_channel* ast_channel_walk_locked ( const struct ast_channel prev  ) 

Browse channels in use Browse the channels currently in use.

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

Definition at line 1076 of file channel.c.

References channel_find_locked().

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

01077 {
01078    return channel_find_locked(prev, NULL, 0, NULL, NULL);
01079 }

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

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

Referenced by channel_spy().

04911 {
04912    if (!chan->whisper)
04913       return -1;
04914 
04915    ast_mutex_lock(&chan->whisper->lock);
04916    ast_slinfactory_feed(&chan->whisper->sf, f);
04917    ast_mutex_unlock(&chan->whisper->lock);
04918 
04919    return 0;
04920 }

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:
Note: This function performs no locking; you must hold the channel's lock before calling this function.

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

04896 {
04897    if (chan->whisper)
04898       return -1;
04899 
04900    if (!(chan->whisper = ast_calloc(1, sizeof(*chan->whisper))))
04901       return -1;
04902 
04903    ast_mutex_init(&chan->whisper->lock);
04904    ast_slinfactory_init(&chan->whisper->sf);
04905    ast_set_flag(chan, AST_FLAG_WHISPER);
04906 
04907    return 0;
04908 }

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 4922 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::original_format, ast_channel_whisper_buffer::path, ast_channel::whisper, and ast_channel::writeformat.

Referenced by ast_channel_free(), and channel_spy().

04923 {
04924    if (!chan->whisper)
04925       return;
04926 
04927    ast_clear_flag(chan, AST_FLAG_WHISPER);
04928    if (chan->whisper->path)
04929       ast_translator_free_path(chan->whisper->path);
04930    if (chan->whisper->original_format && chan->writeformat == AST_FORMAT_SLINEAR)
04931       ast_set_write_format(chan, chan->whisper->original_format);
04932    ast_slinfactory_destroy(&chan->whisper->sf);
04933    ast_mutex_destroy(&chan->whisper->lock);
04934    free(chan->whisper);
04935    chan->whisper = NULL;
04936 }

void ast_channels_init ( void   ) 

Provided by channel.c

Definition at line 4473 of file channel.c.

References ast_cli_register_multiple(), and cli_channel.

Referenced by main().

04474 {
04475    ast_cli_register_multiple(cli_channel, sizeof(cli_channel) / sizeof(struct ast_cli_entry));
04476 }

struct ast_variable* ast_channeltype_list ( void   ) 

return an ast_variable list of channeltypes

Definition at line 180 of file channel.c.

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

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

int ast_check_hangup ( struct ast_channel chan  ) 

Check to see if a channel is needing hang up.

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

Definition at line 402 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_call(), ast_cdr_update(), 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(), handle_sendimage(), pbx_exec(), rpt(), rpt_exec(), zt_sendtext(), and zt_setoption().

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

static int ast_check_hangup_locked ( struct ast_channel chan  )  [static]

Definition at line 416 of file channel.c.

References ast_channel_lock, ast_channel_unlock, and ast_check_hangup().

Referenced by ast_channel_bridge().

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

void ast_deactivate_generator ( struct ast_channel chan  ) 

Deactive an active generator

Definition at line 1782 of file channel.c.

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

Referenced by __ast_read(), app_exec(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_playtones_stop(), ast_quiet_chan(), ast_tonepair_stop(), ast_write(), channel_spy(), generator_force(), local_ast_moh_stop(), milliwatt_exec(), moh_on_off(), and wait_for_answer().

01783 {
01784    ast_channel_lock(chan);
01785    if (chan->generatordata) {
01786       if (chan->generator && chan->generator->release)
01787          chan->generator->release(chan, chan->generatordata);
01788       chan->generatordata = NULL;
01789       chan->generator = NULL;
01790       chan->fds[AST_GENERATOR_FD] = -1;
01791       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
01792       ast_settimeout(chan, 0, NULL, NULL);
01793    }
01794    ast_channel_unlock(chan);
01795 }

int ast_do_masquerade ( struct ast_channel original  ) 

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

Note:
Assumes channel will be locked when called

Definition at line 3437 of file channel.c.

References ast_channel::_state, ast_channel::alertpipe, ast_channel_lock, AST_LIST_FIRST, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_TRAVERSE, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_string_field_set, ast_channel::cdr, ast_channel_spy::chan, EVENT_FLAG_CALL, free_translation(), ast_channel::lock, ast_channel_spy::lock, LOG_DEBUG, manager_event(), ast_channel::masq, ast_channel::masqr, name, option_debug, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::spies, t, ast_channel::tech, ast_channel::tech_pvt, 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().

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

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

References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_RETRY, ast_jb_do_usecheck(), config, f, ast_channel::nativeformats, and ast_channel::tech_pvt.

Referenced by ast_channel_bridge().

03828 {
03829    /* Copy voice back and forth between the two channels. */
03830    struct ast_channel *cs[3];
03831    struct ast_frame *f;
03832    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03833    int o0nativeformats;
03834    int o1nativeformats;
03835    int watch_c0_dtmf;
03836    int watch_c1_dtmf;
03837    void *pvt0, *pvt1;
03838    /* Indicates whether a frame was queued into a jitterbuffer */
03839    int frame_put_in_jb = 0;
03840    int jb_in_use;
03841    int to;
03842    
03843    cs[0] = c0;
03844    cs[1] = c1;
03845    pvt0 = c0->tech_pvt;
03846    pvt1 = c1->tech_pvt;
03847    o0nativeformats = c0->nativeformats;
03848    o1nativeformats = c1->nativeformats;
03849    watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
03850    watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
03851 
03852    /* Check the need of a jitterbuffer for each channel */
03853    jb_in_use = ast_jb_do_usecheck(c0, c1);
03854 
03855    for (;;) {
03856       struct ast_channel *who, *other;
03857 
03858       if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
03859           (o0nativeformats != c0->nativeformats) ||
03860           (o1nativeformats != c1->nativeformats)) {
03861          /* Check for Masquerade, codec changes, etc */
03862          res = AST_BRIDGE_RETRY;
03863          break;
03864       }
03865       if (bridge_end.tv_sec) {
03866          to = ast_tvdiff_ms(bridge_end, ast_tvnow());
03867          if (to <= 0) {
03868             if (config->timelimit)
03869                res = AST_BRIDGE_RETRY;
03870             else
03871                res = AST_BRIDGE_COMPLETE;
03872             break;
03873          }
03874       } else
03875          to = -1;
03876       /* Calculate the appropriate max sleep interval - in general, this is the time,
03877          left to the closest jb delivery moment */
03878       if (jb_in_use)
03879          to = ast_jb_get_when_to_wakeup(c0, c1, to);
03880       who = ast_waitfor_n(cs, 2, &to);
03881       if (!who) {
03882          /* No frame received within the specified timeout - check if we have to deliver now */
03883          if (jb_in_use)
03884             ast_jb_get_and_deliver(c0, c1);
03885          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
03886             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03887                c0->_softhangup = 0;
03888             if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03889                c1->_softhangup = 0;
03890             c0->_bridge = c1;
03891             c1->_bridge = c0;
03892          }
03893          continue;
03894       }
03895       f = ast_read(who);
03896       if (!f) {
03897          *fo = NULL;
03898          *rc = who;
03899          if (option_debug)
03900             ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
03901          break;
03902       }
03903 
03904       other = (who == c0) ? c1 : c0; /* the 'other' channel */
03905       /* Try add the frame info the who's bridged channel jitterbuff */
03906       if (jb_in_use)
03907          frame_put_in_jb = !ast_jb_put(other, f);
03908 
03909       if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
03910          int bridge_exit = 0;
03911 
03912          switch (f->subclass) {
03913          case AST_CONTROL_HOLD:
03914          case AST_CONTROL_UNHOLD:
03915          case AST_CONTROL_VIDUPDATE:
03916             ast_indicate_data(other, f->subclass, f->data, f->datalen);
03917             break;
03918          default:
03919             *fo = f;
03920             *rc = who;
03921             bridge_exit = 1;
03922             if (option_debug)
03923                ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
03924             break;
03925          }
03926          if (bridge_exit)
03927             break;
03928       }
03929       if ((f->frametype == AST_FRAME_VOICE) ||
03930           (f->frametype == AST_FRAME_DTMF_BEGIN) ||
03931           (f->frametype == AST_FRAME_DTMF) ||
03932           (f->frametype == AST_FRAME_VIDEO) ||
03933           (f->frametype == AST_FRAME_IMAGE) ||
03934           (f->frametype == AST_FRAME_HTML) ||
03935           (f->frametype == AST_FRAME_MODEM) ||
03936           (f->frametype == AST_FRAME_TEXT)) {
03937          /* monitored dtmf causes exit from bridge */
03938          int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
03939 
03940          if (monitored_source && 
03941             (f->frametype == AST_FRAME_DTMF_END || 
03942             f->frametype == AST_FRAME_DTMF_BEGIN)) {
03943             *fo = f;
03944             *rc = who;
03945             if (option_debug)
03946                ast_log(LOG_DEBUG, "Got DTMF %s on channel (%s)\n", 
03947                   f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
03948                   who->name);
03949             break;
03950          }
03951          /* Write immediately frames, not passed through jb */
03952          if (!frame_put_in_jb)
03953             ast_write(other, f);
03954             
03955          /* Check if we have to deliver now */
03956          if (jb_in_use)
03957             ast_jb_get_and_deliver(c0, c1);
03958       }
03959       /* XXX do we want to pass on also frames not matched above ? */
03960       ast_frfree(f);
03961 
03962       /* Swap who gets priority */
03963       cs[2] = cs[0];
03964       cs[0] = cs[1];
03965       cs[1] = cs[2];
03966    }
03967    return res;
03968 }

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

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

Definition at line 1101 of file channel.c.

References channel_find_locked().

01102 {
01103    return channel_find_locked(NULL, NULL, 0, context, exten);
01104 }

struct ast_channel* ast_get_channel_by_name_locked ( const char *  name  ) 

Get channel by name (locks channel).

Definition at line 1082 of file channel.c.

References channel_find_locked().

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

01083 {
01084    return channel_find_locked(NULL, name, 0, NULL, NULL);
01085 }

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

Get channel by name prefix (locks channel).

Definition at line 1088 of file channel.c.

References channel_find_locked().

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

01089 {
01090    return channel_find_locked(NULL, name, namelen, NULL, NULL);
01091 }

struct ast_channel_tech* ast_get_channel_tech ( const char *  name  ) 

Get a channel technology structure by name.

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

Definition at line 563 of file channel.c.

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

Referenced by ast_device_state().

00564 {
00565    struct chanlist *chanls;
00566    const struct ast_channel_tech *ret = NULL;
00567 
00568    if (AST_LIST_LOCK(&channels)) {
00569       ast_log(LOG_WARNING, "Unable to lock channel tech list\n");
00570       return NULL;
00571    }
00572 
00573    AST_LIST_TRAVERSE(&backends, chanls, list) {
00574       if (!strcasecmp(name, chanls->tech->type)) {
00575          ret = chanls->tech;
00576          break;
00577       }
00578    }
00579 
00580    AST_LIST_UNLOCK(&channels);
00581    
00582    return ret;
00583 }

ast_group_t ast_get_group ( const char *  s  ) 

Definition at line 4397 of file channel.c.

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

Referenced by _parse(), build_device(), build_gateway(), build_peer(), func_channel_write(), process_zap(), and read_agent_config().

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

int ast_hangup ( struct ast_channel chan  ) 

Hang up a channel.

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

Definition at line 1667 of file channel.c.

References 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_request_and_dial(), __oh323_new(), agent_hangup(), agent_read(), alsa_new(), app_exec(), ast_async_goto(), ast_bridge_call_thread(), ast_dial_destroy(), ast_dial_hangup(), ast_feature_request_and_dial(), ast_iax2_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), begin_dial(), build_conf(), builtin_atxfer(), chanavail_exec(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_free(), conf_run(), do_hang(), do_parking_thread(), features_hangup(), findmeexec(), function_ilink(), gtalk_new(), 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().

01668 {
01669    int res = 0;
01670 
01671    /* Don't actually hang up a channel that will masquerade as someone else, or
01672       if someone is going to masquerade as us */
01673    ast_channel_lock(chan);
01674 
01675    detach_spies(chan);     /* get rid of spies */
01676 
01677    if (chan->masq) {
01678       if (ast_do_masquerade(chan))
01679          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01680    }
01681 
01682    if (chan->masq) {
01683       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
01684       ast_channel_unlock(chan);
01685       return 0;
01686    }
01687    /* If this channel is one which will be masqueraded into something,
01688       mark it as a zombie already, so we know to free it later */
01689    if (chan->masqr) {
01690       ast_set_flag(chan, AST_FLAG_ZOMBIE);
01691       ast_channel_unlock(chan);
01692       return 0;
01693    }
01694    free_translation(chan);
01695    /* Close audio stream */
01696    if (chan->stream) {
01697       ast_closestream(chan->stream);
01698       chan->stream = NULL;
01699    }
01700    /* Close video stream */
01701    if (chan->vstream) {
01702       ast_closestream(chan->vstream);
01703       chan->vstream = NULL;
01704    }
01705    if (chan->sched) {
01706       sched_context_destroy(chan->sched);
01707       chan->sched = NULL;
01708    }
01709    
01710    if (chan->generatordata)   /* Clear any tone stuff remaining */
01711       chan->generator->release(chan, chan->generatordata);
01712    chan->generatordata = NULL;
01713    chan->generator = NULL;
01714    if (chan->cdr) {     /* End the CDR if it hasn't already */
01715       ast_cdr_end(chan->cdr);
01716       ast_cdr_detach(chan->cdr); /* Post and Free the CDR */
01717       chan->cdr = NULL;
01718    }
01719    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01720       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
01721                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
01722                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
01723       CRASH;
01724    }
01725    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
01726       if (option_debug)
01727          ast_log(LOG_DEBUG, "Hanging up channel '%s'\n", chan->name);
01728       if (chan->tech->hangup)
01729          res = chan->tech->hangup(chan);
01730    } else {
01731       if (option_debug)
01732          ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
01733    }
01734          
01735    ast_channel_unlock(chan);
01736    manager_event(EVENT_FLAG_CALL, "Hangup",
01737          "Channel: %s\r\n"
01738          "Uniqueid: %s\r\n"
01739          "Cause: %d\r\n"
01740          "Cause-txt: %s\r\n",
01741          chan->name,
01742          chan->uniqueid,
01743          chan->hangupcause,
01744          ast_cause2str(chan->hangupcause)
01745          );
01746    ast_channel_free(chan);
01747    return res;
01748 }

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

References ast_indicate_data().

Referenced by __ast_play_and_record(), agent_new(), ast_bridge_call(), 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(), handle_remote_data(), handle_remote_phone_dtmf(), mgcp_ss(), monitor_dial(), park_exec(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), rmt_telem_finish(), rmt_telem_start(), rpt(), rpt_exec(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), sla_trunk_exec(), and wait_for_answer().

02485 {
02486    return ast_indicate_data(chan, condition, NULL, 0);
02487 }

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_HOLD with payload being music on hold class
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 2489 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, and ast_channel::zone.

Referenced by __login_exec(), agent_hangup(), ast_indicate(), ast_park_call(), bridge_native_loop(), bridge_p2p_loop(), do_parking_thread(), pbx_builtin_waitexten(), and wait_for_answer().

02490 {
02491    int res = -1;
02492 
02493    ast_channel_lock(chan);
02494    /* Stop if we're a zombie or need a soft hangup */
02495    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02496       ast_channel_unlock(chan);
02497       return -1;
02498    }
02499    if (chan->tech->indicate)
02500       res = chan->tech->indicate(chan, condition, data, datalen);
02501    ast_channel_unlock(chan);
02502    if (!chan->tech->indicate || res) {
02503       /*
02504        * Device does not support (that) indication, lets fake
02505        * it by doing our own tone generation. (PM2002)
02506        */
02507       if (condition < 0)
02508          ast_playtones_stop(chan);
02509       else {
02510          const struct tone_zone_sound *ts = NULL;
02511          switch (condition) {
02512          case AST_CONTROL_RINGING:
02513             ts = ast_get_indication_tone(chan->zone, "ring");
02514             break;
02515          case AST_CONTROL_BUSY:
02516             ts = ast_get_indication_tone(chan->zone, "busy");
02517             break;
02518          case AST_CONTROL_CONGESTION:
02519             ts = ast_get_indication_tone(chan->zone, "congestion");
02520             break;
02521          }
02522          if (ts && ts->data[0]) {
02523             if (option_debug)
02524                ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
02525             ast_playtones_start(chan,0,ts->data, 1);
02526             res = 0;
02527          } else if (condition == AST_CONTROL_PROGRESS) {
02528             /* ast_playtones_stop(chan); */
02529          } else if (condition == AST_CONTROL_PROCEEDING) {
02530             /* Do nothing, really */
02531          } else if (condition == AST_CONTROL_HOLD) {
02532             /* Do nothing.... */
02533          } else if (condition == AST_CONTROL_UNHOLD) {
02534             /* Do nothing.... */
02535          } else if (condition == AST_CONTROL_VIDUPDATE) {
02536             /* Do nothing.... */
02537          } else {
02538             /* not handled */
02539             ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
02540             res = -1;
02541          }
02542       }
02543    }
02544    return res;
02545 }

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

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by load_module(), and reload().

04433 {
04434    ast_moh_start_ptr = start_ptr;
04435    ast_moh_stop_ptr = stop_ptr;
04436    ast_moh_cleanup_ptr = cleanup_ptr;
04437 }

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

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

Referenced by __ast_read(), and add_sdp().

02467 {
02468    int ret = ast_opt_internal_timing && chan->timingfd > -1;
02469    if (option_debug > 4)
02470       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);
02471    return ret;
02472 }

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

References ast_moh_cleanup_ptr.

Referenced by ast_channel_free().

04468 {
04469    if (ast_moh_cleanup_ptr)
04470       ast_moh_cleanup_ptr(chan);
04471 }

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

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

Referenced by alsa_indicate(), app_exec(), 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().

04448 {
04449    if (ast_moh_start_ptr)
04450       return ast_moh_start_ptr(chan, mclass, interpclass);
04451 
04452    if (option_verbose > 2) {
04453       ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n", 
04454          mclass ? mclass : (interpclass ? interpclass : "default"));
04455    }
04456 
04457    return 0;
04458 }

void ast_moh_stop ( struct ast_channel chan  ) 

Turn off music on hold on a given channel.

Turn off music on hold on a given channel

Definition at line 4461 of file channel.c.

References ast_moh_stop_ptr.

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

04462 {
04463    if (ast_moh_stop_ptr)
04464       ast_moh_stop_ptr(chan);
04465 }

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

print call- and pickup groups into buffer

Definition at line 4479 of file channel.c.

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

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

int ast_prod ( struct ast_channel chan  ) 

Send empty audio to prime a channel driver.

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

02668 {
02669    struct ast_frame a = { AST_FRAME_VOICE };
02670    char nothing[128];
02671 
02672    /* Send an empty audio frame to get things moving */
02673    if (chan->_state != AST_STATE_UP) {
02674       if (option_debug)
02675          ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
02676       a.subclass = chan->rawwriteformat;
02677       a.data = nothing + AST_FRIENDLY_OFFSET;
02678       a.src = "ast_prod";
02679       if (ast_write(chan, &a))
02680          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
02681    }
02682    return 0;
02683 }

int ast_queue_control ( struct ast_channel chan,
enum ast_control_frame_type  control 
)

Queue a control frame with payload.

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

Definition at line 951 of file channel.c.

References AST_FRAME_CONTROL, ast_queue_frame(), and f.

Referenced by __oh323_update_info(), __zt_exception(), ast_pickup_call(), attempt_transfer(), auto_congest(), gtalk_is_answered(), gtalk_ringing_ack(), handle_hd_hf(), handle_offhook_message(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_refer(), handle_response(), handle_response_invite(), handle_response_refer(), handle_soft_key_event_message(), handle_stimulus_message(), mgcp_call(), nbs_call(), phone_call(), pickup_do(), process_sdp(), receive_digit(), send_cause2ast(), setup_rtp_connection(), skinny_call(), skinny_unhold(), socket_process(), ss_thread(), update_state(), zt_handle_event(), and zt_hangup().

00952 {
00953    struct ast_frame f = { AST_FRAME_CONTROL, };
00954 
00955    f.subclass = control;
00956 
00957    return ast_queue_frame(chan, &f);
00958 }

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

References AST_FRAME_CONTROL, ast_queue_frame(), and f.

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

00963 {
00964    struct ast_frame f = { AST_FRAME_CONTROL, };
00965 
00966    f.subclass = control;
00967    f.data = (void *) data;
00968    f.datalen = datalen;
00969 
00970    return ast_queue_frame(chan, &f);
00971 }

int ast_queue_frame ( struct ast_channel chan,
struct ast_frame fin 
)

Queue an outgoing frame.

Definition at line 883 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, 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_channel_masquerade(), ast_channel_setwhentohangup(), 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(), wakeup_sub(), and zap_queue_frame().

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

int ast_queue_hangup ( struct ast_channel chan  ) 

Queue a hangup frame.

Definition at line 939 of file channel.c.

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

Referenced by __oh323_update_info(), __sip_autodestruct(), cleanup_connection(), console_hangup(), console_hangup_deprecated(), gtalk_hangup_farend(), handle_onhook_message(), handle_request_bye(), handle_request_cancel(), handle_response(), handle_response_invite(), handle_soft_key_event_message(), hangup_chan(), hangup_connection(), iax2_destroy(), iax2_predestroy(), mgcp_queue_hangup(), misdn_answer(), retrans_pkt(), and zt_handle_event().

00940 {
00941    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
00942    /* Yeah, let's not change a lock-critical value without locking */
00943    if (!ast_channel_trylock(chan)) {
00944       chan->_softhangup |= AST_SOFTHANGUP_DEV;
00945       ast_channel_unlock(chan);
00946    }
00947    return ast_queue_frame(chan, &f);
00948 }

struct ast_frame* ast_read ( struct ast_channel chan  ) 

Reads 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.

Definition at line 2474 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_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_parking_thread(), do_waiting(), echo_exec(), features_read(), find_cache(), handle_invite_replaces(), handle_recordfile(), iax_park_thread(), ices_exec(), isAnsweringMachine(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), mwanalyze_exec(), NBScat_exec(), nv_background_detect_exec(), nv_detectfax_exec(), receive_dtmf_digits(), recordthread(), rpt(), run_agi(), rxfax_exec(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), speech_background(), ss_thread(), txfax_exec(), wait_for_answer(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), waitstream_core(), and zt_bridge().

02475 {
02476    return __ast_read(chan, 0);
02477 }

struct ast_frame* ast_read_noaudio ( struct ast_channel chan  ) 

Reads a frame, returning AST_FRAME_NULL frame if audio.

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

References __ast_read().

Referenced by conf_run().

02480 {
02481    return __ast_read(chan, 1);
02482 }

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

03182 {
03183    return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
03184 }

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

03187 {
03188    int pos = 0;   /* index in the buffer where we accumulate digits */
03189    int to = ftimeout;
03190 
03191    /* Stop if we're a zombie or need a soft hangup */
03192    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03193       return -1;
03194    if (!len)
03195       return -1;
03196    for (;;) {
03197       int d;
03198       if (c->stream) {
03199          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
03200          ast_stopstream(c);
03201          usleep(1000);
03202          if (!d)
03203             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03204       } else {
03205          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03206       }
03207       if (d < 0)
03208          return -1;
03209       if (d == 0) {
03210          s[pos]='\0';
03211          return 1;
03212       }
03213       if (d == 1) {
03214          s[pos]='\0';
03215          return 2;
03216       }
03217       if (!strchr(enders, d))
03218          s[pos++] = d;
03219       if (strchr(enders, d) || (pos >= len)) {
03220          s[pos]='\0';
03221          return 0;
03222       }
03223       to = timeout;
03224    }
03225    /* Never reached */
03226    return 0;
03227 }

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

References ast_recvtext(), and free.

Referenced by handle_recvchar().

02548 {
02549    int c;
02550    char *buf = ast_recvtext(chan, timeout);
02551    if (buf == NULL)
02552       return -1;  /* error or timeout */
02553    c = *(unsigned char *)buf;
02554    free(buf);
02555    return c;
02556 }

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

References ast_check_hangup(), AST_CONTROL_HANGUP, AST_FRAME_CONTROL, AST_FRAME_TEXT, ast_frfree(), ast_read(), ast_strndup, ast_waitfor(), and f.

Referenced by ast_recvchar(), and handle_recvtext().

02559 {
02560    int res, done = 0;
02561    char *buf = NULL;
02562    
02563    while (!done) {
02564       struct ast_frame *f;
02565       if (ast_check_hangup(chan))
02566          break;
02567       res = ast_waitfor(chan, timeout);
02568       if (res <= 0) /* timeout or error */
02569          break;
02570       timeout = res; /* update timeout */
02571       f = ast_read(chan);
02572       if (f == NULL)
02573          break; /* no frame */
02574       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
02575          done = 1;   /* force a break */
02576       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
02577          buf = ast_strndup((char *) f->data, f->datalen);   /* dup and break */
02578          done = 1;
02579       }
02580       ast_frfree(f);
02581    }
02582    return buf;
02583 }

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

Requests a channel.

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

Definition at line 3090 of file channel.c.

References 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(), capabilities, ast_channel_tech::capabilities, fmt, LOG_WARNING, ast_channel_tech::requester, chanlist::tech, and ast_channel_tech::type.

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

03091 {
03092    struct chanlist *chan;
03093    struct ast_channel *c;
03094    int capabilities;
03095    int fmt;
03096    int res;
03097    int foo;
03098    int videoformat = format & AST_FORMAT_VIDEO_MASK;
03099 
03100    if (!cause)
03101       cause = &foo;
03102    *cause = AST_CAUSE_NOTDEFINED;
03103 
03104    if (AST_LIST_LOCK(&channels)) {
03105       ast_log(LOG_WARNING, "Unable to lock channel list\n");
03106       return NULL;
03107    }
03108 
03109    AST_LIST_TRAVERSE(&backends, chan, list) {
03110       if (strcasecmp(type, chan->tech->type))
03111          continue;
03112 
03113       capabilities = chan->tech->capabilities;
03114       fmt = format & AST_FORMAT_AUDIO_MASK;
03115       res = ast_translator_best_choice(&fmt, &capabilities);
03116       if (res < 0) {
03117          ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
03118          AST_LIST_UNLOCK(&channels);
03119          return NULL;
03120       }
03121       AST_LIST_UNLOCK(&channels);
03122       if (!chan->tech->requester)
03123          return NULL;
03124       
03125       if (!(c = chan->tech->requester(type, capabilities | videoformat, data, cause)))
03126          return NULL;
03127 
03128       /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
03129       return c;
03130    }
03131 
03132    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
03133    *cause = AST_CAUSE_NOSUCHDRIVER;
03134    AST_LIST_UNLOCK(&channels);
03135 
03136    return NULL;
03137 }

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

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

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

Definition at line 3085 of file channel.c.

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_exten().

03086 {
03087    return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
03088 }

int ast_safe_sleep ( struct ast_channel chan,
int  ms 
)

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

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

Definition at line 1135 of file channel.c.

References ast_safe_sleep_conditional().

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

01136 {
01137    return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
01138 }

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

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

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

Definition at line 1114 of file channel.c.

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

Referenced by __login_exec(), and ast_safe_sleep().

01115 {
01116    struct ast_frame *f;
01117 
01118    while (ms > 0) {
01119       if (cond && ((*cond)(data) == 0))
01120          return 0;
01121       ms = ast_waitfor(chan, ms);
01122       if (ms < 0)
01123          return -1;
01124       if (ms > 0) {
01125          f = ast_read(chan);
01126          if (!f)
01127             return -1;
01128          ast_frfree(f);
01129       }
01130    }
01131    return 0;
01132 }

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

References ast_malloc, and len.

Referenced by features_new().

00427 {
00428    char *b2,buf[1];
00429    int len;
00430 
00431    va_list args;
00432    va_start(args, fmt);
00433    len = vsnprintf(buf, 1, fmt, args);
00434    b2 = ast_malloc(len+1);
00435    vsnprintf(b2, len+1,  fmt, args);
00436    va_end(args);
00437    return b2;
00438 }

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

Definition at line 4874 of file channel.c.

References ast_say_character_str_full.

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

04876 {
04877         return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
04878 }

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

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

04870 {
04871         return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
04872 }

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

Definition at line 4862 of file channel.c.

References ast_say_digits_full().

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

04864 {
04865         return ast_say_digits_full(chan, num, ints, lang, -1, -1);
04866 }

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

Definition at line 4886 of file channel.c.

References ast_say_digit_str_full.

Referenced by __say_init(), ast_say_digits(), ast_say_enumeration_full_da(), ast_say_enumeration_full_de(), ast_say_number_full_cz(), ast_say_number_full_da(), ast_say_number_full_de(), ast_say_number_full_en(), ast_say_number_full_en_GB(), ast_say_number_full_es(), ast_say_number_full_fr(), ast_say_number_full_ge(), ast_say_number_full_he(), ast_say_number_full_it(), ast_say_number_full_nl(), ast_say_number_full_no(), ast_say_number_full_pt(), ast_say_number_full_ru(), ast_say_number_full_se(), and ast_say_number_full_tw().

04888 {
04889         char buf[256];
04890 
04891         snprintf(buf, sizeof(buf), "%d", num);
04892         return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
04893 }

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

Definition at line 4856 of file channel.c.

References ast_say_enumeration_full.

Referenced by ast_say_date_da(), ast_say_date_de(), ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), and ast_say_date_with_format_pl().

04858 {
04859         return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
04860 }

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

Definition at line 4850 of file channel.c.

References ast_say_number_full.

Referenced by ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_ge(), ast_say_date_gr(), ast_say_date_nl(), ast_say_date_pt(), ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), ast_say_date_with_format_es(), ast_say_date_with_format_fr(), ast_say_date_with_format_it(), ast_say_date_with_format_nl(), ast_say_date_with_format_pl(), ast_say_date_with_format_pt(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_ge(), ast_say_datetime_from_now_pt(), ast_say_datetime_pt(), ast_say_datetime_tw(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_ge(), ast_say_time_gr(), ast_say_time_nl(), ast_say_time_pt(), ast_say_time_pt_BR(), ast_say_time_tw(), bridge_playfile(), conf_exec(), conf_run(), count_exec(), dictate_exec(), get_folder(), gr_say_number_female(), pbx_builtin_saynumber(), play_message(), play_message_duration(), rpt_tele_thread(), say_and_wait(), say_position(), saynum(), try_calling(), vm_intro_gr(), vm_intro_pt(), and vm_intro_pt_BR().

04852 {
04853         return ast_say_number_full(chan, num, ints, language, options, -1, -1);
04854 }

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

Definition at line 4880 of file channel.c.

References ast_say_phonetic_str_full.

Referenced by pbx_builtin_sayphonetic().

04882 {
04883         return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
04884 }

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

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

Referenced by ast_dtmf_stream(), and manager_play_dtmf().

02658 {
02659    if (chan->tech->send_digit_begin) {
02660       ast_senddigit_begin(chan, digit);
02661       ast_safe_sleep(chan, 100); /* XXX 100ms ... probably should be configurable */
02662    }
02663    
02664    return ast_senddigit_end(chan, digit, 100);
02665 }

int ast_senddigit_begin ( 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 2598 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().

02599 {
02600    /* Device does not support DTMF tones, lets fake
02601     * it by doing our own generation. */
02602    static const char* dtmf_tones[] = {
02603       "941+1336", /* 0 */
02604       "697+1209", /* 1 */
02605       "697+1336", /* 2 */
02606       "697+1477", /* 3 */
02607       "770+1209", /* 4 */
02608       "770+1336", /* 5 */
02609       "770+1477", /* 6 */
02610       "852+1209", /* 7 */
02611       "852+1336", /* 8 */
02612       "852+1477", /* 9 */
02613       "697+1633", /* A */
02614       "770+1633", /* B */
02615       "852+1633", /* C */
02616       "941+1633", /* D */
02617       "941+1209", /* * */
02618       "941+1477"  /* # */
02619    };
02620 
02621    if (!chan->tech->send_digit_begin)
02622       return 0;
02623 
02624    if (!chan->tech->send_digit_begin(chan, digit))
02625       return 0;
02626 
02627    if (digit >= '0' && digit <='9')
02628       ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
02629    else if (digit >= 'A' && digit <= 'D')
02630       ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
02631    else if (digit == '*')
02632       ast_playtones_start(chan, 0, dtmf_tones[14], 0);
02633    else if (digit == '#')
02634       ast_playtones_start(chan, 0, dtmf_tones[15], 0);
02635    else {
02636       /* not handled */
02637       if (option_debug)
02638          ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
02639    }
02640 
02641    return 0;
02642 }

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

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

02645 {
02646    int res = -1;
02647 
02648    if (chan->tech->send_digit_end)
02649       res = chan->tech->send_digit_end(chan, digit, duration);
02650 
02651    if (res && chan->generator)
02652       ast_playtones_stop(chan);
02653    
02654    return 0;
02655 }

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

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

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

Definition at line 2585 of file channel.c.

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

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

02586 {
02587    int res = 0;
02588    /* Stop if we're a zombie or need a soft hangup */
02589    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02590       return -1;
02591    CHECK_BLOCKING(chan);
02592    if (chan->tech->send_text)
02593       res = chan->tech->send_text(chan, text);
02594    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02595    return res;
02596 }

void ast_set_callerid ( struct ast_channel chan,
const char *  callerid,
const char *  calleridname,
const char *  ani 
)

Definition at line 3722 of file channel.c.

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

03723 {
03724    if (callerid) {
03725       if (chan->cid.cid_num)
03726          free(chan->cid.cid_num);
03727       chan->cid.cid_num = ast_strdup(callerid);
03728    }
03729    if (calleridname) {
03730       if (chan->cid.cid_name)
03731          free(chan->cid.cid_name);
03732       chan->cid.cid_name = ast_strdup(calleridname);
03733    }
03734    if (ani) {
03735       if (chan->cid.cid_ani)
03736          free(chan->cid.cid_ani);
03737       chan->cid.cid_ani = ast_strdup(ani);
03738    }
03739    if (chan->cdr)
03740       ast_cdr_setcid(chan->cdr, chan);
03741    manager_event(EVENT_FLAG_CALL, "Newcallerid",
03742             "Channel: %s\r\n"
03743             "CallerID: %s\r\n"
03744             "CallerIDName: %s\r\n"
03745             "Uniqueid: %s\r\n"
03746             "CID-CallingPres: %d (%s)\r\n",
03747             chan->name,
03748             S_OR(chan->cid.cid_num, "<Unknown>"),
03749             S_OR(chan->cid.cid_name, "<Unknown>"),
03750             chan->uniqueid,
03751             chan->cid.cid_pres,
03752             ast_describe_caller_presentation(chan->cid.cid_pres)
03753             );
03754 }

int ast_set_read_format ( struct ast_channel chan,
int  format 
)

Sets read format on channel chan Set read format for channel to whichever component of "format" is best.

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

Definition at line 2949 of file channel.c.

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

Referenced by __ast_play_and_record(), __login_exec(), __oh323_update_info(), agent_call(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_channel_formats_reset(), ast_channel_make_compatible(), ast_set_best_format(), attempt_reconnect(), background_detect_exec(), build_conf(), conf_run(), dictate_exec(), disa_exec(), do_waiting(), eagi_exec(), echo_exec(), function_ilink(), gtalk_rtp_read(), handle_recordfile(), ices_exec(), isAnsweringMachine(), measurenoise(), mgcp_rtp_read(), milliwatt_exec(), mwanalyze_exec(), nv_background_detect_exec(), nv_detectfax_exec(), oh323_rtp_read(), process_sdp(), rpt(), rpt_exec(), rxfax_exec(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), txfax_exec(), and update_features().

02950 {
02951    return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
02952            &chan->readtrans, 0);
02953 }

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 4504 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_app(), and ast_pbx_outgoing_exten().

04505 {
04506    struct ast_variable *cur;
04507 
04508    for (cur = vars; cur; cur = cur->next)
04509       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
04510 }

int ast_set_write_format ( struct ast_channel chan,
int  format 
)

Sets write format on channel chan Set write format for channel to whichever compoent of "format" is best.

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

Definition at line 2955 of file channel.c.

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

Referenced by __login_exec(), __oh323_update_info(), agent_call(), alarmreceiver_exec(), ast_adsi_transmit_message_full(), ast_channel_formats_reset(), ast_channel_make_compatible(), ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_channel_whisper_stop(), ast_openstream_full(), ast_set_best_format(), ast_stopstream(), ast_write(), attempt_reconnect(), build_conf(), channel_spy(), chanspy_exec(), conf_run(), disa_exec(), echo_exec(), extenspy_exec(), function_ilink(), gtalk_rtp_read(), linear_alloc(), linear_release(), mgcp_rtp_read(), milliwatt_exec(), moh_alloc(), moh_files_release(), moh_release(), mp3_exec(), mwanalyze_exec(), NBScat_exec(), oh323_rtp_read(), playtones_alloc(), playtones_release(), process_sdp(), rpt(), rpt_exec(), rxfax_exec(), send_waveform_to_channel(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), tonepair_alloc(), tonepair_release(), txfax_exec(), and update_features().

02956 {
02957    return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
02958            &chan->writetrans, 1);
02959 }

int ast_setstate ( struct ast_channel chan,
enum ast_channel_state  state 
)

Change the state of a channel.

Definition at line 3756 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_read(), __oh323_update_info(), __zt_exception(), agent_call(), alsa_answer(), ast_answer(), cb_events(), check_availability(), gtalk_call(), gtalk_newcall(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_response_invite(), handle_soft_key_event_message(), handle_stimulus_message(), iax2_call(), mgcp_answer(), mgcp_call(), mgcp_ss(), misdn_call(), misdn_indication(), nbs_call(), nbs_hangup(), oh323_answer(), oss_answer(), pbx_builtin_busy(), pbx_builtin_congestion(), phone_answer(), phone_call(), phone_exception(), phone_hangup(), phone_write(), release_chan(), sip_answer(), skinny_answer(), skinny_call(), skinny_newcall(), ss_thread(), update_state(), zt_answer(), zt_call(), zt_handle_event(), zt_indicate(), and zt_read().

03757 {
03758    int oldstate = chan->_state;
03759 
03760    if (oldstate == state)
03761       return 0;
03762 
03763    chan->_state = state;
03764    ast_device_state_changed_literal(chan->name);
03765    /* setstate used to conditionally report Newchannel; this is no more */
03766    manager_event(EVENT_FLAG_CALL,
03767             "Newstate",
03768             "Channel: %s\r\n"
03769             "State: %s\r\n"
03770             "CallerID: %s\r\n"
03771             "CallerIDName: %s\r\n"
03772             "Uniqueid: %s\r\n",
03773             chan->name, ast_state2str(chan->_state),
03774             S_OR(chan->cid.cid_num, "<unknown>"),
03775             S_OR(chan->cid.cid_name, "<unknown>"),
03776             chan->uniqueid);
03777 
03778    return 0;
03779 }

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

Definition at line 2021 of file channel.c.

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

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

02022 {
02023    int res = -1;
02024 #ifdef HAVE_ZAPTEL
02025    if (c->timingfd > -1) {
02026       if (!func) {
02027          samples = 0;
02028          data = 0;
02029       }
02030       if (option_debug)
02031          ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
02032       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
02033       c->timingfunc = func;
02034       c->timingdata = data;
02035    }
02036 #endif   
02037    return res;
02038 }

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

References shutting_down.

00473 {
00474    return shutting_down;
00475 }

int ast_softhangup ( struct ast_channel chan,
int  cause 
)

Softly hangup up a channel.

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

Definition at line 1525 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_softhangup_nolock(), and ast_channel_spy::chan.

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

01526 {
01527    int res;
01528    ast_channel_lock(chan);
01529    res = ast_softhangup_nolock(chan, cause);
01530    ast_channel_unlock(chan);
01531    return res;
01532 }

int ast_softhangup_nolock ( struct ast_channel chan,
int  cause 
)

Softly hangup up a channel (no channel lock).

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

Definition at line 1511 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, ast_channel_spy::chan, LOG_DEBUG, and option_debug.

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

01512 {
01513    if (option_debug)
01514       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
01515    /* Inform channel driver that we need to be hung up, if it cares */
01516    chan->_softhangup |= cause;
01517    ast_queue_frame(chan, &ast_null_frame);
01518    /* Interrupt any poll call or such */
01519    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
01520       pthread_kill(chan->blocker, SIGURG);
01521    return 0;
01522 }

char* ast_state2str ( enum  ast_channel_state  ) 

Gives the string form of a given channel state.

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

Definition at line 611 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_setstate(), attempt_transfer(), func_channel_read(), handle_chanlist(), handle_chanlist_deprecated(), handle_invite_replaces(), handle_showchan(), handle_showchan_deprecated(), local_attended_transfer(), mgcp_new(), serialize_showchan(), and sip_hangup().

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

int ast_str2cause ( const char *  name  ) 

Convert a symbolic hangup cause to number.

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

Definition at line 599 of file channel.c.

References causes.

Referenced by pbx_builtin_hangup().

00600 {
00601    int x;
00602 
00603    for (x = 0; x < sizeof(causes) / sizeof(causes[0]); x++)
00604       if (strncasecmp(causes[x].name, name, strlen(causes[x].name)) == 0)
00605          return causes[x].cause;
00606 
00607    return -1;
00608 }

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

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

Referenced by zapateller_exec().

04380 {
04381    int res;
04382 
04383    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
04384       return res;
04385 
04386    /* Give us some wiggle room */
04387    while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
04388       struct ast_frame *f = ast_read(chan);
04389       if (f)
04390          ast_frfree(f);
04391       else
04392          return -1;
04393    }
04394    return 0;
04395 }

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

Start a tone going

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

04362 {
04363    struct tonepair_def d = { 0, };
04364 
04365    d.freq1 = freq1;
04366    d.freq2 = freq2;
04367    d.duration = duration;
04368    d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */
04369    if (ast_activate_generator(chan, &tonepair, &d))
04370       return -1;
04371    return 0;
04372 }

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 4374 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

04375 {
04376    ast_deactivate_generator(chan);
04377 }

int ast_transfer ( struct ast_channel chan,
char *  dest 
)

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

Called by:

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

03164 {
03165    int res = -1;
03166 
03167    /* Stop if we're a zombie or need a soft hangup */
03168    ast_channel_lock(chan);
03169    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03170       if (chan->tech->transfer) {
03171          res = chan->tech->transfer(chan, dest);
03172          if (!res)
03173             res = 1;
03174       } else
03175          res = 0;
03176    }
03177    ast_channel_unlock(chan);
03178    return res;
03179 }

char* ast_transfercapability2str ( int  transfercapability  )  const

Gives the string form of a given transfer capability.

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

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

00646 {
00647    switch(transfercapability) {
00648    case AST_TRANS_CAP_SPEECH:
00649       return "SPEECH";
00650    case AST_TRANS_CAP_DIGITAL:
00651       return "DIGITAL";
00652    case AST_TRANS_CAP_RESTRICTED_DIGITAL:
00653       return "RESTRICTED_DIGITAL";
00654    case AST_TRANS_CAP_3_1K_AUDIO:
00655       return "3K1AUDIO";
00656    case AST_TRANS_CAP_DIGITAL_W_TONES:
00657       return "DIGITAL_W_TONES";
00658    case AST_TRANS_CAP_VIDEO:
00659       return "VIDEO";
00660    default:
00661       return "UNKNOWN";
00662    }
00663 }

void ast_uninstall_music_functions ( void   ) 

Definition at line 4439 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

04440 {
04441    ast_moh_start_ptr = NULL;
04442    ast_moh_stop_ptr = NULL;
04443    ast_moh_cleanup_ptr = NULL;
04444 }

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 2005 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(), mwanalyze_exec(), NBScat_exec(), nv_background_detect_exec(), nv_detectfax_exec(), receive_dtmf_digits(), recordthread(), rxfax_exec(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), speech_background(), ss_thread(), txfax_exec(), wait_for_hangup(), waitforring_exec(), and waitstream_core().

02006 {
02007    int oldms = ms;   /* -1 if no timeout */
02008 
02009    ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
02010    if ((ms < 0) && (oldms < 0))
02011       ms = 0;
02012    return ms;
02013 }

struct ast_channel* ast_waitfor_n ( struct ast_channel **  chan,
int  n,
int *  ms 
)

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

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

Definition at line 2000 of file channel.c.

References ast_waitfor_nandfds().

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

02001 {
02002    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
02003 }

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

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

Definition at line 1845 of file channel.c.

References ast_waitfor_nandfds().

Referenced by dundi_lookup_internal(), and dundi_precache_internal().

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

struct ast_channel* ast_waitfor_nandfds ( struct ast_channel **  chan,
int  n,
int *  fds,
int  nfds,
int *  exception,
int *  outfd,
int *  ms 
)

Waits for activity on a group of channels.

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

Definition at line 1853 of file channel.c.

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

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

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

int ast_waitfordigit ( struct ast_channel c,
int  ms 
)

Waits for a digit.

!

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

Definition at line 2016 of file channel.c.

References ast_waitfordigit_full().

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

02017 {
02018    return ast_waitfordigit_full(c, ms, -1, -1);
02019 }

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

References ast_check_hangup(), AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VOICE, ast_frfree(), ast_log(), ast_read(), ast_test_flag, ast_waitfor_nandfds(), f, and LOG_WARNING.

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

02041 {
02042 
02043    /* Stop if we're a zombie or need a soft hangup */
02044    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
02045       return -1;
02046    /* Wait for a digit, no more than ms milliseconds total. */
02047    while (ms) {
02048       struct ast_channel *rchan;
02049       int outfd;
02050 
02051       errno = 0;
02052       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
02053       if (!rchan && outfd < 0 && ms) {
02054          if (errno == 0 || errno == EINTR)
02055             continue;
02056          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
02057          return -1;
02058       } else if (outfd > -1) {
02059          /* The FD we were watching has something waiting */
02060          return 1;
02061       } else if (rchan) {
02062          int res;
02063          struct ast_frame *f = ast_read(c);
02064          if (!f)
02065             return -1;
02066 
02067          switch(f->frametype) {
02068          case AST_FRAME_DTMF:
02069             res = f->subclass;
02070             ast_frfree(f);
02071             return res;
02072          case AST_FRAME_CONTROL:
02073             switch(f->subclass) {
02074             case AST_CONTROL_HANGUP:
02075                ast_frfree(f);
02076                return -1;
02077             case AST_CONTROL_RINGING:
02078             case AST_CONTROL_ANSWER:
02079                /* Unimportant */
02080                break;
02081             default:
02082                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
02083                break;
02084             }
02085             break;
02086          case AST_FRAME_VOICE:
02087             /* Write audio if appropriate */
02088             if (audiofd > -1)
02089                write(audiofd, f->data, f->datalen);
02090          default:
02091             /* Ignore */
02092             break;
02093          }
02094          ast_frfree(f);
02095       }
02096    }
02097    return 0; /* Time is up */
02098 }

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

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

Definition at line 1107 of file channel.c.

References channel_find_locked().

Referenced by next_channel().

01109 {
01110    return channel_find_locked(chan, NULL, 0, context, exten);
01111 }

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

Get channel by name prefix (locks channel).

Definition at line 1094 of file channel.c.

References channel_find_locked().

Referenced by next_channel().

01096 {
01097    return channel_find_locked(chan, name, namelen, NULL, NULL);
01098 }

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

References ast_channel::_softhangup, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, 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_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, MONITOR_DELAY, ast_channel_whisper_buffer::original_format, ast_channel::outsmpl, ast_channel_whisper_buffer::path, queue_frame_to_spies(), ast_channel::rawwriteformat, 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_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(), jb_get_and_deliver(), linear_generator(), milliwatt_generate(), misdn_bridge(), moh_files_generator(), moh_generate(), mp3_exec(), mwanalyze_exec(), NBScat_exec(), rpt(), rpt_call(), rxfax_exec(), send_link_dtmf(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), spy_generate(), txfax_exec(), wait_for_answer(), and zt_bridge().

02697 {
02698    int res = -1;
02699    struct ast_frame *f = NULL;
02700 
02701    /* Stop if we're a zombie or need a soft hangup */
02702    ast_channel_lock(chan);
02703    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02704       goto done;
02705 
02706    /* Handle any pending masquerades */
02707    if (chan->masq && ast_do_masquerade(chan)) {
02708       ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02709       goto done;
02710    }
02711    if (chan->masqr) {
02712       res = 0; /* XXX explain, why 0 ? */
02713       goto done;
02714    }
02715    if (chan->generatordata) {
02716       if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
02717          ast_deactivate_generator(chan);
02718       else {
02719          if (fr->frametype == AST_FRAME_DTMF_END) {
02720             /* There is a generator running while we're in the middle of a digit.
02721              * It's probably inband DTMF, so go ahead and pass it so it can
02722              * stop the generator */
02723             ast_clear_flag(chan, AST_FLAG_BLOCKING);
02724             ast_channel_unlock(chan);
02725             res = ast_senddigit_end(chan, fr->subclass, fr->len);
02726             ast_channel_lock(chan);
02727             CHECK_BLOCKING(chan);
02728          }
02729 
02730          res = 0; /* XXX explain, why 0 ? */
02731          goto done;
02732       }
02733    }
02734    /* High bit prints debugging */
02735    if (chan->fout & DEBUGCHAN_FLAG)
02736       ast_frame_dump(chan->name, fr, ">>");
02737    CHECK_BLOCKING(chan);
02738    switch(fr->frametype) {
02739    case AST_FRAME_CONTROL:
02740       res = (chan->tech->indicate == NULL) ? 0 :
02741          chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
02742       break;
02743    case AST_FRAME_DTMF_BEGIN:
02744       ast_clear_flag(chan, AST_FLAG_BLOCKING);
02745       ast_channel_unlock(chan);
02746       res = ast_senddigit_begin(chan, fr->subclass);
02747       ast_channel_lock(chan);
02748       CHECK_BLOCKING(chan);
02749       break;
02750    case AST_FRAME_DTMF_END:
02751       ast_clear_flag(chan, AST_FLAG_BLOCKING);
02752       ast_channel_unlock(chan);
02753       res = ast_senddigit_end(chan, fr->subclass, fr->len);
02754       ast_channel_lock(chan);
02755       CHECK_BLOCKING(chan);
02756       break;
02757    case AST_FRAME_TEXT:
02758       res = (chan->tech->send_text == NULL) ? 0 :
02759          chan->tech->send_text(chan, (char *) fr->data);
02760       break;
02761    case AST_FRAME_HTML:
02762       res = (chan->tech->send_html == NULL) ? 0 :
02763          chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
02764       break;
02765    case AST_FRAME_VIDEO:
02766       /* XXX Handle translation of video codecs one day XXX */
02767       res = (chan->tech->write_video == NULL) ? 0 :
02768          chan->tech->write_video(chan, fr);
02769       break;
02770    case AST_FRAME_MODEM:
02771       res = (chan->tech->write == NULL) ? 0 :
02772          chan->tech->write(chan, fr);
02773       break;
02774    case AST_FRAME_VOICE:
02775       if (chan->tech->write == NULL)
02776          break;   /*! \todo XXX should return 0 maybe ? */
02777 
02778       /* If someone is whispering on this channel then we must ensure that we are always getting signed linear frames */
02779       if (ast_test_flag(chan, AST_FLAG_WHISPER)) {
02780          if (fr->subclass == AST_FORMAT_SLINEAR)
02781             f = fr;
02782          else {
02783             ast_mutex_lock(&chan->whisper->lock);
02784             if (chan->writeformat != AST_FORMAT_SLINEAR) {
02785                /* Rebuild the translation path and set our write format back to signed linear */
02786                chan->whisper->original_format = chan->writeformat;
02787                ast_set_write_format(chan, AST_FORMAT_SLINEAR);
02788                if (chan->whisper->path)
02789                   ast_translator_free_path(chan->whisper->path);
02790                chan->whisper->path = ast_translator_build_path(AST_FORMAT_SLINEAR, chan->whisper->original_format);
02791             }
02792             /* Translate frame using the above translation path */
02793             f = (chan->whisper->path) ? ast_translate(chan->whisper->path, fr, 0) : fr;
02794             ast_mutex_unlock(&chan->whisper->lock);
02795          }
02796       } else {
02797          /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
02798          if (fr->subclass == chan->rawwriteformat)
02799             f = fr;
02800          else
02801             f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
02802       }
02803 
02804       /* If we have no frame of audio, then we have to bail out */
02805       if (f == NULL) {
02806          res = 0;
02807          break;
02808       }
02809 
02810       /* If spies are on the channel then queue the frame out to them */
02811       if (chan->spies)
02812          queue_frame_to_spies(chan, f, SPY_WRITE);
02813 
02814       /* If Monitor is running on this channel, then we have to write frames out there too */
02815       if (chan->monitor && chan->monitor->write_stream) {
02816          /* XXX must explain this code */
02817 #ifndef MONITOR_CONSTANT_DELAY
02818          int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
02819          if (jump >= 0) {
02820             jump = chan->insmpl - chan->outsmpl;
02821             if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
02822                ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02823             chan->outsmpl += jump + f->samples;
02824          } else
02825             chan->outsmpl += f->samples;
02826 #else
02827          int jump = chan->insmpl - chan->outsmpl;
02828          if (jump - MONITOR_DELAY >= 0) {
02829             if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02830                ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02831             chan->outsmpl += jump;
02832          } else
02833             chan->outsmpl += f->samples;
02834 #endif
02835          if (chan->monitor->state == AST_MONITOR_RUNNING) {
02836             if (ast_writestream(chan->monitor->write_stream, f) < 0)
02837                ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
02838          }
02839       }
02840 
02841       /* Finally the good part! Write this out to the channel */
02842       if (ast_test_flag(chan, AST_FLAG_WHISPER)) {
02843          /* frame is assumed to be in SLINEAR, since that is
02844             required for whisper mode */
02845          ast_frame_adjust_volume(f, -2);
02846          if (ast_slinfactory_available(&chan->whisper->sf) >= f->samples) {
02847             short buf[f->samples];
02848             struct ast_frame whisper = {
02849                .frametype = AST_FRAME_VOICE,
02850                .subclass = AST_FORMAT_SLINEAR,
02851                .data = buf,
02852                .datalen = sizeof(buf),
02853                .samples = f->samples,
02854             };
02855             
02856             ast_mutex_lock(&chan->whisper->lock);
02857             if (ast_slinfactory_read(&chan->whisper->sf, buf, f->samples))
02858                ast_frame_slinear_sum(f, &whisper);
02859             ast_mutex_unlock(&chan->whisper->lock);
02860          }
02861          /* and now put it through the regular translator */
02862          f = (chan->writetrans) ? ast_translate(chan->writetrans, f, 0) : f;
02863       }
02864       if (f)
02865          res = chan->tech->write(chan, f);
02866       else
02867          res = 0;
02868       break;
02869    case AST_FRAME_NULL:
02870    case AST_FRAME_IAX:
02871       /* Ignore these */
02872       res = 0;
02873       break;
02874    default:
02875       /* At this point, fr is the incoming frame and f is NULL.  Channels do
02876        * not expect to get NULL as a frame pointer and will segfault.  Hence,
02877        * we output the original frame passed in. */
02878       res = chan->tech->write(chan, fr);
02879       break;
02880    }
02881 
02882    if (f && f != fr)
02883       ast_frfree(f);
02884    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02885    /* Consider a write failure to force a soft hangup */
02886    if (res < 0)
02887       chan->_softhangup |= AST_SOFTHANGUP_DEV;
02888    else {
02889       chan->fout = FRAMECOUNT_INC(chan->fout);
02890    }
02891 done:
02892    ast_channel_unlock(chan);
02893    return res;
02894 }

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

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

02686 {
02687    int res;
02688    if (!chan->tech->write_video)
02689       return 0;
02690    res = ast_write(chan, fr);
02691    if (!res)
02692       res = 1;
02693    return res;
02694 }

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

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

03792 {
03793    int min = 0, sec = 0, check;
03794 
03795    check = ast_autoservice_start(peer);
03796    if (check)
03797       return;
03798 
03799    if (remain > 0) {
03800       if (remain / 60 > 1) {
03801          min = remain / 60;
03802          sec = remain % 60;
03803       } else {
03804          sec = remain;
03805       }
03806    }
03807    
03808    if (!strcmp(sound,"timeleft")) { /* Queue support */
03809       ast_stream_and_wait(chan, "vm-youhave", chan->language, "");
03810       if (min) {
03811          ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
03812          ast_stream_and_wait(chan, "queue-minutes", chan->language, "");
03813       }
03814       if (sec) {
03815          ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
03816          ast_stream_and_wait(chan, "queue-seconds", chan->language, "");
03817       }
03818    } else {
03819       ast_stream_and_wait(chan, sound, chan->language, "");
03820    }
03821 
03822    ast_autoservice_stop(peer);
03823 }

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

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

References ast_channel_trylock, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), 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_walk_channel_by_exten_locked(), and ast_walk_channel_by_name_prefix_locked().

01019 {
01020    const char *msg = prev ? "deadlock" : "initial deadlock";
01021    int retries;
01022    struct ast_channel *c;
01023 
01024    for (retries = 0; retries < 10; retries++) {
01025       int done;
01026       AST_LIST_LOCK(&channels);
01027       AST_LIST_TRAVERSE(&channels, c, chan_list) {
01028          if (prev) { /* look for next item */
01029             if (c != prev) /* not this one */
01030                continue;
01031             /* found, prepare to return c->next */
01032             if ((c = AST_LIST_NEXT(c, chan_list)) == NULL) break;
01033             /* If prev was the last item on the channel list, then we just
01034              * want to return NULL, instead of trying to deref NULL in the
01035              * next section.
01036              */
01037          }
01038          if (name) { /* want match by name */
01039             if ((!namelen && strcasecmp(c->name, name)) ||
01040                 (namelen && strncasecmp(c->name, name, namelen)))
01041                continue;   /* name match failed */
01042          } else if (exten) {
01043             if (context && strcasecmp(c->context, context) &&
01044                 strcasecmp(c->macrocontext, context))
01045                continue;   /* context match failed */
01046             if (strcasecmp(c->exten, exten) &&
01047                 strcasecmp(c->macroexten, exten))
01048                continue;   /* exten match failed */
01049          }
01050          /* if we get here, c points to the desired record */
01051          break;
01052       }
01053       /* exit if chan not found or mutex acquired successfully */
01054       /* this is slightly unsafe, as we _should_ hold the lock to access c->name */
01055       done = c == NULL || ast_channel_trylock(c) == 0;
01056       if (!done)
01057          if (option_debug)
01058             ast_log(LOG_DEBUG, "Avoiding %s for channel '%p'\n", msg, c);
01059       AST_LIST_UNLOCK(&channels);
01060       if (done)
01061          return c;
01062       usleep(1);  /* give other threads a chance before retrying */
01063    }
01064    /*
01065     * c is surely not null, but we don't have the lock so cannot
01066     * access c->name
01067     */
01068    if (option_debug)
01069       ast_log(LOG_DEBUG, "Failure, could not lock '%p' after %d retries!\n",
01070          c, retries);
01071 
01072    return NULL;
01073 }

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

References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.

04715 {
04716    switch (reason) {
04717    case CHANNEL_MODULE_LOAD:
04718       return "LOAD (Channel module load)";
04719 
04720    case CHANNEL_MODULE_RELOAD:
04721       return "RELOAD (Channel module reload)";
04722 
04723    case CHANNEL_CLI_RELOAD:
04724       return "CLIRELOAD (Channel module reload by CLI command)";
04725 
04726    default:
04727       return "MANAGERRELOAD (Channel module reload by manager)";
04728    }
04729 };

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

References AST_LIST_APPEND_LIST, AST_LIST_FIRST, and ast_channel::varshead.

03425 {
03426    /* Append variables from clone channel into original channel */
03427    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
03428    if (AST_LIST_FIRST(&clone->varshead))
03429       AST_LIST_APPEND_LIST(&original->varshead, &clone->varshead, entries);
03430 }

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

Definition at line 351 of file channel.c.

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

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

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

Definition at line 329 of file channel.c.

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

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

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

Definition at line 4512 of file channel.c.

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

Referenced by ast_channel_spy_read_frame().

04513 {
04514    struct ast_frame *f;
04515    int tocopy;
04516    int bytestocopy;
04517 
04518    while (samples) {
04519       if (!(f = AST_LIST_FIRST(&queue->list))) {
04520          ast_log(LOG_ERROR, "Ran out of frames before buffer filled!\n");
04521          break;
04522       }
04523 
04524       tocopy = (f->samples > samples) ? samples : f->samples;
04525       bytestocopy = ast_codec_get_len(queue->format, tocopy);
04526       memcpy(buf, f->data, bytestocopy);
04527       samples -= tocopy;
04528       buf += tocopy;
04529       f->samples -= tocopy;
04530       f->data += bytestocopy;
04531       f->datalen -= bytestocopy;
04532       f->offset += bytestocopy;
04533       queue->samples -= tocopy;
04534 
04535       if (!f->samples)
04536          ast_frfree(AST_LIST_REMOVE_HEAD(&queue->list, frame_list));
04537    }
04538 }

static void detach_spies ( struct ast_channel chan  )  [static]

Definition at line 1494 of file channel.c.

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

Referenced by ast_hangup().

01495 {
01496    struct ast_channel_spy *spy = NULL;
01497 
01498    if (!chan->spies)
01499       return;
01500 
01501    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) {
01502       AST_LIST_REMOVE_CURRENT(&chan->spies->list, list);
01503       spy_detach(spy, chan);
01504    }
01505    AST_LIST_TRAVERSE_SAFE_END
01506 
01507    spy_cleanup(chan);
01508 }

static void free_cid ( struct ast_callerid cid  )  [static]

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

01141 {
01142    if (cid->cid_dnid)
01143       free(cid->cid_dnid);
01144    if (cid->cid_num)
01145       free(cid->cid_num);  
01146    if (cid->cid_name)
01147       free(cid->cid_name); 
01148    if (cid->cid_ani)
01149       free(cid->cid_ani);
01150    if (cid->cid_rdnis)
01151       free(cid->cid_rdnis);
01152 }

static void free_translation ( struct ast_channel clone  )  [static]

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

01655 {
01656    if (clone->writetrans)
01657       ast_translator_free_path(clone->writetrans);
01658    if (clone->readtrans)
01659       ast_translator_free_path(clone->readtrans);
01660    clone->writetrans = NULL;
01661    clone->readtrans = NULL;
01662    clone->rawwriteformat = clone->nativeformats;
01663    clone->rawreadformat = clone->nativeformats;
01664 }

static int generator_force ( void *  data  )  [static]

Definition at line 1797 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_read(), and ast_activate_generator().

01798 {
01799    /* Called if generator doesn't have data */
01800    void *tmp;
01801    int res;
01802    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
01803    struct ast_channel *chan = data;
01804    tmp = chan->generatordata;
01805    chan->generatordata = NULL;
01806    generate = chan->generator->generate;
01807    res = generate(chan, tmp, 0, 160);
01808    chan->generatordata = tmp;
01809    if (res) {
01810       if (option_debug)
01811          ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01812       ast_deactivate_generator(chan);
01813    }
01814    return 0;
01815 }

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

Definition at line 1541 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_TRIGGER_FLUSH, CHANSPY_TRIGGER_MODE, CHANSPY_TRIGGER_NONE, CHANSPY_TRIGGER_READ, CHANSPY_TRIGGER_WRITE, f, 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::trigger, ast_channel_spy::type, ast_channel_spy::write_queue, and ast_channel_spy_list::write_translator.

Referenced by __ast_read(), and ast_write().

01542 {
01543    struct ast_frame *translated_frame = NULL;
01544    struct ast_channel_spy *spy;
01545    struct channel_spy_trans *trans;
01546 
01547    trans = (dir == SPY_READ) ? &chan->spies->read_translator : &chan->spies->write_translator;
01548 
01549    AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
01550       struct ast_channel_spy_queue *queue;
01551       struct ast_frame *duped_fr;
01552 
01553       ast_mutex_lock(&spy->lock);
01554 
01555       queue = (dir == SPY_READ) ? &spy->read_queue : &spy->write_queue;
01556 
01557       if ((queue->format == AST_FORMAT_SLINEAR) && (f->subclass != AST_FORMAT_SLINEAR)) {
01558          if (!translated_frame) {
01559             if (trans->path && (trans->last_format != f->subclass)) {
01560                ast_translator_free_path(trans->path);
01561                trans->path = NULL;
01562             }
01563             if (!trans->path) {
01564                if (option_debug)
01565                   ast_log(LOG_DEBUG, "Building translator from %s to SLINEAR for spies on channel %s\n",
01566                      ast_getformatname(f->subclass), chan->name);
01567                if ((trans->path = ast_translator_build_path(AST_FORMAT_SLINEAR, f->subclass)) == NULL) {
01568                   ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n",
01569                      ast_getformatname(f->subclass), ast_getformatname(AST_FORMAT_SLINEAR));
01570                   ast_mutex_unlock(&spy->lock);
01571                   continue;
01572                } else {
01573                   trans->last_format = f->subclass;
01574                }
01575             }
01576             if (!(translated_frame = ast_translate(trans->path, f, 0))) {
01577                ast_log(LOG_ERROR, "Translation to %s failed, dropping frame for spies\n",
01578                   ast_getformatname(AST_FORMAT_SLINEAR));
01579                ast_mutex_unlock(&spy->lock);
01580                break;
01581             }
01582          }
01583          duped_fr = ast_frdup(translated_frame);
01584       } else if (f->subclass != queue->format) {
01585          ast_log(LOG_WARNING, "Spy '%s' on channel '%s' wants format '%s', but frame is '%s', dropping\n",
01586             spy->type, chan->name,
01587             ast_getformatname(queue->format), ast_getformatname(f->subclass));
01588          ast_mutex_unlock(&spy->lock);
01589          continue;
01590       } else
01591          duped_fr = ast_frdup(f);
01592 
01593       AST_LIST_INSERT_TAIL(&queue->list, duped_fr, frame_list);
01594 
01595       queue->samples += f->samples;
01596 
01597       if (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) {
01598          if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) {
01599             switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) {
01600             case CHANSPY_TRIGGER_READ:
01601                if (dir == SPY_WRITE) {
01602                   ast_set_flag(spy, CHANSPY_TRIGGER_WRITE);
01603                   ast_clear_flag(spy, CHANSPY_TRIGGER_READ);
01604                   if (option_debug)
01605                      ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to write-trigger mode\n",
01606                         spy->type, chan->name);
01607                }
01608                break;
01609             case CHANSPY_TRIGGER_WRITE:
01610                if (dir == SPY_READ) {
01611                   ast_set_flag(spy, CHANSPY_TRIGGER_READ);
01612                   ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE);
01613                   if (option_debug)
01614                      ast_log(LOG_DEBUG, "Switching spy '%s' on '%s' to read-trigger mode\n",
01615                         spy->type, chan->name);
01616                }
01617                break;
01618             }
01619             if (option_debug)
01620                ast_log(LOG_DEBUG, "Triggering queue flush for spy '%s' on '%s'\n",
01621                   spy->type, chan->name);
01622             ast_set_flag(spy, CHANSPY_TRIGGER_FLUSH);
01623             ast_cond_signal(&spy->trigger);
01624          } else {
01625             if (option_debug)
01626                ast_log(LOG_DEBUG, "Spy '%s' on channel '%s' %s queue too long, dropping frames\n",
01627                   spy->type, chan->name, (dir == SPY_READ) ? "read" : "write");
01628             while (queue->samples > SPY_QUEUE_SAMPLE_LIMIT) {
01629                struct ast_frame *drop = AST_LIST_REMOVE_HEAD(&queue->list, frame_list);
01630                queue->samples -= drop->samples;
01631                ast_frfree(drop);
01632             }
01633          }
01634       } else {
01635          switch (ast_test_flag(spy, CHANSPY_TRIGGER_MODE)) {
01636          case CHANSPY_TRIGGER_READ:
01637             if (dir == SPY_READ)
01638                ast_cond_signal(&spy->trigger);
01639             break;
01640          case CHANSPY_TRIGGER_WRITE:
01641             if (dir == SPY_WRITE)
01642                ast_cond_signal(&spy->trigger);
01643             break;
01644          }
01645       }
01646 
01647       ast_mutex_unlock(&spy->lock);
01648    }
01649 
01650    if (translated_frame)
01651       ast_frfree(translated_frame);
01652 }

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

02898 {
02899    int native;
02900    int res;
02901    
02902    /* Make sure we only consider audio */
02903    fmt &= AST_FORMAT_AUDIO_MASK;
02904    
02905    native = chan->nativeformats;
02906    /* Find a translation path from the native format to one of the desired formats */
02907    if (!direction)
02908       /* reading */
02909       res = ast_translator_best_choice(&fmt, &native);
02910    else
02911       /* writing */
02912       res = ast_translator_best_choice(&native, &fmt);
02913 
02914    if (res < 0) {
02915       ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
02916          ast_getformatname(native), ast_getformatname(fmt));
02917       return -1;
02918    }
02919    
02920    /* Now we have a good choice for both. */
02921    ast_channel_lock(chan);
02922 
02923    if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
02924       /* the channel is already in these formats, so nothing to do */
02925       ast_channel_unlock(chan);
02926       return 0;
02927    }
02928 
02929    *rawformat = native;
02930    /* User perspective is fmt */
02931    *format = fmt;
02932    /* Free any read translation we have right now */
02933    if (*trans)
02934       ast_translator_free_path(*trans);
02935    /* Build a translation path from the raw format to the desired format */
02936    if (!direction)
02937       /* reading */
02938       *trans = ast_translator_build_path(*format, *rawformat);
02939    else
02940       /* writing */
02941       *trans = ast_translator_build_path(*rawformat, *format);
02942    ast_channel_unlock(chan);
02943    if (option_debug)
02944       ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name,
02945          direction ? "write" : "read", ast_getformatname(fmt));
02946    return 0;
02947 }

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

Definition at line 276 of file channel.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_channel_tech::capabilities, 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.

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

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

Definition at line 223 of file channel.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_channel_tech::capabilities, 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.

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

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

Definition at line 196 of file channel.c.

References ast_cli(), AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), 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.

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

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

Definition at line 4635 of file channel.c.

04636 {
04637    /* just store the data pointer in the channel structure */
04638    return data;
04639 }

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

Definition at line 4646 of file channel.c.

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

04647 {
04648    short buf[samples];
04649    struct ast_frame frame = {
04650       .frametype = AST_FRAME_VOICE,
04651       .subclass = AST_FORMAT_SLINEAR,
04652       .data = buf,
04653       .samples = samples,
04654       .datalen = sizeof(buf),
04655    };
04656    memset(buf, 0, sizeof(buf));
04657    if (ast_write(chan, &frame))
04658       return -1;
04659    return 0;
04660 }

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

Definition at line 4641 of file channel.c.

04642 {
04643    /* nothing to do */
04644 }

static void spy_cleanup ( struct ast_channel chan  )  [static]

Definition at line 1389 of file channel.c.

References AST_LIST_EMPTY, ast_translator_free_path(), free, channel_spy_trans::path, ast_channel_spy_list::read_translator, ast_channel::spies, and ast_channel_spy_list::write_translator.

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

01390 {
01391    if (!AST_LIST_EMPTY(&chan->spies->list))
01392       return;
01393    if (chan->spies->read_translator.path)
01394       ast_translator_free_path(chan->spies->read_translator.path);
01395    if (chan->spies->write_translator.path)
01396       ast_translator_free_path(chan->spies->write_translator.path);
01397    free(chan->spies);
01398    chan->spies = NULL;
01399    return;
01400 }

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

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

01404 {
01405    ast_mutex_lock(&spy->lock);
01406 
01407    /* We only need to poke them if they aren't already done */
01408    if (spy->status != CHANSPY_DONE) {
01409       /* Indicate to the spy to stop */
01410       spy->status = CHANSPY_STOP;
01411       spy->chan = NULL;
01412       /* Poke the spy if needed */
01413       if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
01414          ast_cond_signal(&spy->trigger);
01415    }
01416 
01417    /* Print it out while we still have a lock so the structure can't go away (if signalled above) */
01418    if (option_debug)
01419       ast_log(LOG_DEBUG, "Spy %s removed from channel %s\n", spy->type, chan->name);
01420 
01421    ast_mutex_unlock(&spy->lock);
01422 
01423    return;
01424 }

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

Definition at line 4279 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_def::freq1, tonepair_def::freq2, LOG_WARNING, tonepair_release(), tonepair_def::vol, and ast_channel::writeformat.

04280 {
04281    struct tonepair_state *ts;
04282    struct tonepair_def *td = params;
04283 
04284    if (!(ts = ast_calloc(1, sizeof(*ts))))
04285       return NULL;
04286    ts->origwfmt = chan->writeformat;
04287    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
04288       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
04289       tonepair_release(NULL, ts);
04290       ts = NULL;
04291    } else {
04292       ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
04293       ts->v1_1 = 0;
04294       ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
04295       ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
04296       ts->v2_1 = 0;
04297       ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
04298       ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
04299       ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
04300       ts->duration = td->duration;
04301       ts->modulate = 0;
04302    }
04303    /* Let interrupts interrupt :) */
04304    ast_set_flag(chan, AST_FLAG_WRITE_INT);
04305    return ts;
04306 }

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

Definition at line 4308 of file channel.c.

References ast_log(), tonepair_state::data, tonepair_state::f, tonepair_state::fac1, tonepair_state::fac2, LOG_WARNING, tonepair_state::modulate, 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.

04309 {
04310    struct tonepair_state *ts = data;
04311    int x;
04312 
04313    /* we need to prepare a frame with 16 * timelen samples as we're
04314     * generating SLIN audio
04315     */
04316    len = samples * 2;
04317 
04318    if (len > sizeof(ts->data) / 2 - 1) {
04319       ast_log(LOG_WARNING, "Can't generate that much data!\n");
04320       return -1;
04321    }
04322    memset(&ts->f, 0, sizeof(ts->f));
04323    for (x=0;x<len/2;x++) {
04324       ts->v1_1 = ts->v2_1;
04325       ts->v2_1 = ts->v3_1;
04326       ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
04327       
04328       ts->v1_2 = ts->v2_2;
04329       ts->v2_2 = ts->v3_2;
04330       ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
04331       if (ts->modulate) {
04332          int p;
04333          p = ts->v3_2 - 32768;
04334          if (p < 0) p = -p;
04335          p = ((p * 9) / 10) + 1;
04336          ts->data[x] = (ts->v3_1 * p) >> 15;
04337       } else
04338          ts->data[x] = ts->v3_1 + ts->v3_2; 
04339    }
04340    ts->f.frametype = AST_FRAME_VOICE;
04341    ts->f.subclass = AST_FORMAT_SLINEAR;
04342    ts->f.datalen = len;
04343    ts->f.samples = samples;
04344    ts->f.offset = AST_FRIENDLY_OFFSET;
04345    ts->f.data = ts->data;
04346    ast_write(chan, &ts->f);
04347    ts->pos += x;
04348    if (ts->duration > 0) {
04349       if (ts->pos >= ts->duration * 8)
04350          return -1;
04351    }
04352    return 0;
04353 }

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

Definition at line 4270 of file channel.c.

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

Referenced by tonepair_alloc().

04271 {
04272    struct tonepair_state *ts = params;
04273 
04274    if (chan)
04275       ast_set_write_format(chan, ts->origwfmt);
04276    free(ts);
04277 }


Variable Documentation

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

Definition at line 4428 of file channel.c.

Referenced by ast_install_music_functions(), ast_moh_cleanup(), and ast_uninstall_music_functions().

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

Definition at line 4426 of file channel.c.

Referenced by ast_install_music_functions(), ast_moh_start(), and ast_uninstall_music_functions().

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

Definition at line 4427 of file channel.c.

Referenced by ast_install_music_functions(), ast_moh_stop(), and ast_uninstall_music_functions().

struct ast_cause causes[]

map AST_CAUSE's to readable string representations

Referenced by ast_cause2str(), ast_str2cause(), and dump_cause().

struct ast_cli_entry cli_channel[] [static]

Definition at line 391 of file channel.c.

Referenced by ast_channels_init().

struct ast_cli_entry cli_show_channeltype_deprecated [static]

Initial value:

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

Definition at line 386 of file channel.c.

struct ast_cli_entry cli_show_channeltypes_deprecated [static]

Initial value:

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

Definition at line 381 of file channel.c.

unsigned long global_fin

Definition at line 100 of file channel.c.

unsigned long global_fout

Definition at line 100 of file channel.c.

struct ast_channel_tech null_tech [static]

Initial value:

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

Definition at line 714 of file channel.c.

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

int shutting_down [static]

Prevent new channel allocation if shutting down.

Definition at line 96 of file channel.c.

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

struct ast_generator silence_generator [static]

Initial value:

Definition at line 4662 of file channel.c.

Referenced by ast_channel_start_silence_generator().

struct ast_generator tonepair [static]

Initial value:

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

Definition at line 4355 of file channel.c.

Referenced by ast_tonepair_start().

int uniqueint [static]

Definition at line 98 of file channel.c.


Generated on Mon May 14 04:45:52 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1