Mon Mar 31 07:39:46 2008

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/audiohook.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_silence_generator
struct  chanlist
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 STATE2STR_BUFSIZE   32

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_inherit (struct ast_channel *from, struct ast_channel *to)
 Inherit datastores from a parent to a child.
int ast_channel_datastore_remove (struct ast_channel *chan, struct ast_datastore *datastore)
 Remove a datastore from a channel.
int ast_channel_defer_dtmf (struct ast_channel *chan)
 Set defer DTMF flag on channel.
void ast_channel_free (struct ast_channel *chan)
 Free a channel structure.
void ast_channel_inherit_variables (const struct ast_channel *parent, struct ast_channel *child)
 Inherits channel variable from parent to child channel.
int ast_channel_make_compatible (struct ast_channel *chan, struct ast_channel *peer)
 Makes two channel formats compatible.
int ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone)
 Weird function made for call transfers.
char * ast_channel_reason2str (int reason)
 return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument
int ast_channel_register (const struct ast_channel_tech *tech)
 Register a 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.
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.
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.
static void ast_read_generator_actions (struct ast_channel *chan, struct ast_frame *f)
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)(const void *data), void *data)
int ast_shutting_down (void)
 Returns non-zero if Asterisk is being shut down.
int ast_softhangup (struct ast_channel *chan, int cause)
 Softly hangup up a channel.
int ast_softhangup_nolock (struct ast_channel *chan, int cause)
 Softly hangup up a channel (no channel lock).
char * ast_state2str (enum ast_channel_state 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 free_cid (struct ast_callerid *cid)
static void free_translation (struct ast_channel *clone)
static int generator_force (const void *data)
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 * 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 89 of file channel.c.

Referenced by __ast_read(), and ast_senddigit().

#define AST_MIN_DTMF_DURATION   80

Minimum allowed digit length - 80ms

Definition at line 92 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 96 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 74 of file channel.c.

#define MONITOR_DELAY   150 * 8

Definition at line 75 of file channel.c.

Referenced by __ast_read(), and ast_write().

#define STATE2STR_BUFSIZE   32

Definition at line 85 of file channel.c.

Referenced by ast_state2str().


Function Documentation

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

Definition at line 1914 of file channel.c.

References ast_channel::_softhangup, ast_channel::_state, ast_channel::alertpipe, AST_AUDIOHOOK_DIRECTION_READ, ast_audiohook_write_list(), ast_cdr_alloc(), ast_cdr_answer(), ast_cdr_end(), ast_cdr_init(), ast_cdr_start(), ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, ast_deactivate_generator(), AST_DEFAULT_EMULATE_DTMF_DURATION, ast_do_masquerade(), AST_FLAG_DEFER_DTMF, AST_FLAG_EMULATE_DTMF, AST_FLAG_END_DTMF_ONLY, AST_FLAG_EXCEPTION, AST_FLAG_IN_DTMF, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree, AST_GENERATOR_FD, ast_getformatname(), AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_NEXT, AST_LIST_REMOVE_HEAD, ast_log(), AST_MIN_DTMF_DURATION, AST_MIN_DTMF_GAP, AST_MONITOR_RUNNING, ast_null_frame, ast_read_generator_actions(), ast_seekstream(), ast_set_flag, ast_setstate(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_strlen_zero(), ast_test_flag, AST_TIMING_FD, ast_translate(), ast_writestream(), ast_channel::audiohooks, 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, errno, 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, ast_channel::generatordata, ast_channel::insmpl, LOG_DEBUG, LOG_DTMF, LOG_NOTICE, ast_channel::masq, ast_channel::monitor, MONITOR_DELAY, ast_channel::nativeformats, option_debug, ast_channel::outsmpl, ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readtrans, SEEK_FORCECUR, 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().

01915 {
01916    struct ast_frame *f = NULL;   /* the return value */
01917    int blah;
01918    int prestate;
01919    int count = 0;
01920 
01921    /* this function is very long so make sure there is only one return
01922     * point at the end (there are only two exceptions to this).
01923     */
01924    while(ast_channel_trylock(chan)) {
01925       if(count++ > 10) 
01926          /*cannot goto done since the channel is not locked*/
01927          return &ast_null_frame;
01928       usleep(1);
01929    }
01930 
01931    if (chan->masq) {
01932       if (ast_do_masquerade(chan))
01933          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01934       else
01935          f =  &ast_null_frame;
01936       goto done;
01937    }
01938 
01939    /* Stop if we're a zombie or need a soft hangup */
01940    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01941       if (chan->generator)
01942          ast_deactivate_generator(chan);
01943       goto done;
01944    }
01945    prestate = chan->_state;
01946 
01947    if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF | AST_FLAG_IN_DTMF) && 
01948        !ast_strlen_zero(chan->dtmfq) && 
01949       (ast_tvzero(chan->dtmf_tv) || ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) > AST_MIN_DTMF_GAP) ) {
01950       /* We have DTMF that has been deferred.  Return it now */
01951       chan->dtmff.subclass = chan->dtmfq[0];
01952       /* Drop first digit from the buffer */
01953       memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
01954       f = &chan->dtmff;
01955       if (ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
01956          ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
01957          chan->dtmff.frametype = AST_FRAME_DTMF_END;
01958       } else {
01959          ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %d queued on %s\n", f->subclass, AST_DEFAULT_EMULATE_DTMF_DURATION, chan->name);
01960          chan->dtmff.frametype = AST_FRAME_DTMF_BEGIN;
01961          ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
01962          chan->emulate_dtmf_digit = f->subclass;
01963          chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
01964       }
01965       chan->dtmf_tv = ast_tvnow();
01966       goto done;
01967    }
01968    
01969    /* Read and ignore anything on the alertpipe, but read only
01970       one sizeof(blah) per frame that we send from it */
01971    if (chan->alertpipe[0] > -1)
01972       read(chan->alertpipe[0], &blah, sizeof(blah));
01973 
01974 #ifdef HAVE_ZAPTEL
01975    if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
01976       int res;
01977 
01978       ast_clear_flag(chan, AST_FLAG_EXCEPTION);
01979       blah = -1;
01980       /* IF we can't get event, assume it's an expired as-per the old interface */
01981       res = ioctl(chan->timingfd, ZT_GETEVENT, &blah);
01982       if (res)
01983          blah = ZT_EVENT_TIMER_EXPIRED;
01984 
01985       if (blah == ZT_EVENT_TIMER_PING) {
01986          if (AST_LIST_EMPTY(&chan->readq) || !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
01987             /* Acknowledge PONG unless we need it again */
01988             if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) {
01989                ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
01990             }
01991          }
01992       } else if (blah == ZT_EVENT_TIMER_EXPIRED) {
01993          ioctl(chan->timingfd, ZT_TIMERACK, &blah);
01994          if (chan->timingfunc) {
01995             /* save a copy of func/data before unlocking the channel */
01996             int (*func)(const void *) = chan->timingfunc;
01997             void *data = chan->timingdata;
01998             ast_channel_unlock(chan);
01999             func(data);
02000          } else {
02001             blah = 0;
02002             ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
02003             chan->timingdata = NULL;
02004             ast_channel_unlock(chan);
02005          }
02006          /* cannot 'goto done' because the channel is already unlocked */
02007          return &ast_null_frame;
02008       } else
02009          ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
02010    } else
02011 #endif
02012    if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
02013       /* if the AST_GENERATOR_FD is set, call the generator with args
02014        * set to -1 so it can do whatever it needs to.
02015        */
02016       void *tmp = chan->generatordata;
02017       chan->generatordata = NULL;     /* reset to let ast_write get through */
02018       chan->generator->generate(chan, tmp, -1, -1);
02019       chan->generatordata = tmp;
02020       f = &ast_null_frame;
02021       goto done;
02022    }
02023 
02024    /* Check for pending read queue */
02025    if (!AST_LIST_EMPTY(&chan->readq)) {
02026       f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list);
02027       /* Interpret hangup and return NULL */
02028       /* XXX why not the same for frames from the channel ? */
02029       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
02030          ast_frfree(f);
02031          f = NULL;
02032       }
02033    } else {
02034       chan->blocker = pthread_self();
02035       if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02036          if (chan->tech->exception)
02037             f = chan->tech->exception(chan);
02038          else {
02039             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
02040             f = &ast_null_frame;
02041          }
02042          /* Clear the exception flag */
02043          ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02044       } else if (chan->tech->read)
02045          f = chan->tech->read(chan);
02046       else
02047          ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
02048    }
02049 
02050    if (f) {
02051       /* if the channel driver returned more than one frame, stuff the excess
02052          into the readq for the next ast_read call (note that we can safely assume
02053          that the readq is empty, because otherwise we would not have called into
02054          the channel driver and f would be only a single frame)
02055       */
02056       if (AST_LIST_NEXT(f, frame_list)) {
02057          AST_LIST_HEAD_SET_NOLOCK(&chan->readq, AST_LIST_NEXT(f, frame_list));
02058          AST_LIST_NEXT(f, frame_list) = NULL;
02059       }
02060 
02061       switch (f->frametype) {
02062       case AST_FRAME_CONTROL:
02063          if (f->subclass == AST_CONTROL_ANSWER) {
02064             if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02065                if (option_debug)
02066                   ast_log(LOG_DEBUG, "Ignoring answer on an inbound call!\n");
02067                ast_frfree(f);
02068                f = &ast_null_frame;
02069             } else if (prestate == AST_STATE_UP) {
02070                if (option_debug)
02071                   ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
02072                ast_frfree(f);
02073                f = &ast_null_frame;
02074             } else {
02075                /* Answer the CDR */
02076                ast_setstate(chan, AST_STATE_UP);
02077                if (!chan->cdr) { /* up till now, this insertion hasn't been done. Therefore,
02078                                to keep from throwing off the basic order of the universe,
02079                                we will try to keep this cdr from getting posted. */
02080                   chan->cdr = ast_cdr_alloc();
02081                   ast_cdr_init(chan->cdr, chan);
02082                   ast_cdr_start(chan->cdr);
02083                }
02084                
02085                ast_cdr_answer(chan->cdr);
02086             }
02087          }
02088          break;
02089       case AST_FRAME_DTMF_END:
02090          ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass, chan->name, f->len);
02091          /* Queue it up if DTMF is deffered, or if DTMF emulation is forced.
02092           * However, only let emulation be forced if the other end cares about BEGIN frames */
02093          if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF) ||
02094             (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) ) {
02095             if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) {
02096                ast_log(LOG_DTMF, "DTMF end '%c' put into dtmf queue on %s\n", f->subclass, chan->name);
02097                chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
02098             } else
02099                ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
02100             ast_frfree(f);
02101             f = &ast_null_frame;
02102          } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
02103             if (!ast_tvzero(chan->dtmf_tv) && 
02104                 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
02105                /* If it hasn't been long enough, defer this digit */
02106                if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2) {
02107                   ast_log(LOG_DTMF, "DTMF end '%c' put into dtmf queue on %s\n", f->subclass, chan->name);
02108                   chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
02109                } else
02110                   ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
02111                ast_frfree(f);
02112                f = &ast_null_frame;
02113             } else {
02114                /* There was no begin, turn this into a begin and send the end later */
02115                f->frametype = AST_FRAME_DTMF_BEGIN;
02116                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02117                chan->emulate_dtmf_digit = f->subclass;
02118                chan->dtmf_tv = ast_tvnow();
02119                if (f->len) {
02120                   if (f->len > AST_MIN_DTMF_DURATION)
02121                      chan->emulate_dtmf_duration = f->len;
02122                   else 
02123                      chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
02124                } else
02125                   chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
02126                ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass, chan->emulate_dtmf_duration, chan->name);
02127             }
02128             if (chan->audiohooks) {
02129                struct ast_frame *old_frame = f;
02130                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02131                if (old_frame != f)
02132                   ast_frfree(old_frame);
02133                                 }
02134          } else {
02135             struct timeval now = ast_tvnow();
02136             if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02137                ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass, chan->name);
02138                ast_clear_flag(chan, AST_FLAG_IN_DTMF);
02139                if (!f->len)
02140                   f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02141             } else if (!f->len) {
02142                ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass, chan->name);
02143                f->len = AST_MIN_DTMF_DURATION;
02144             }
02145             if (f->len < AST_MIN_DTMF_DURATION) {
02146                ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass, f->len, AST_MIN_DTMF_DURATION, chan->name);
02147                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02148                chan->emulate_dtmf_digit = f->subclass;
02149                chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
02150                ast_frfree(f);
02151                f = &ast_null_frame;
02152             } else {
02153                ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass, chan->name);
02154                chan->dtmf_tv = now;
02155             }
02156             if (chan->audiohooks) {
02157                struct ast_frame *old_frame = f;
02158                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02159                if (old_frame != f)
02160                   ast_frfree(old_frame);
02161             }
02162          }
02163          break;
02164       case AST_FRAME_DTMF_BEGIN:
02165          ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name);
02166          if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) || 
02167              (!ast_tvzero(chan->dtmf_tv) && 
02168                ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
02169             ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass, chan->name);
02170             ast_frfree(f);
02171             f = &ast_null_frame;
02172          } else {
02173             ast_set_flag(chan, AST_FLAG_IN_DTMF);
02174             chan->dtmf_tv = ast_tvnow();
02175             ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass, chan->name);
02176          }
02177          break;
02178       case AST_FRAME_NULL:
02179          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
02180           * is reached , because we want to make sure we pass at least one
02181           * voice frame through before starting the next digit, to ensure a gap
02182           * between DTMF digits. */
02183          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
02184             struct timeval now = ast_tvnow();
02185             if (!chan->emulate_dtmf_duration) {
02186                ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02187                chan->emulate_dtmf_digit = 0;
02188             } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
02189                chan->emulate_dtmf_duration = 0;
02190                ast_frfree(f);
02191                f = &chan->dtmff;
02192                f->frametype = AST_FRAME_DTMF_END;
02193                f->subclass = chan->emulate_dtmf_digit;
02194                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02195                chan->dtmf_tv = now;
02196                ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02197                chan->emulate_dtmf_digit = 0;
02198                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
02199             }
02200          }
02201          break;
02202       case AST_FRAME_VOICE:
02203          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
02204           * is reached , because we want to make sure we pass at least one
02205           * voice frame through before starting the next digit, to ensure a gap
02206           * between DTMF digits. */
02207          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
02208             ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02209             chan->emulate_dtmf_digit = 0;
02210          }
02211 
02212          if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02213             if (dropaudio)
02214                ast_read_generator_actions(chan, f);
02215             ast_frfree(f);
02216             f = &ast_null_frame;
02217          }
02218 
02219          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02220             struct timeval now = ast_tvnow();
02221             if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
02222                chan->emulate_dtmf_duration = 0;
02223                ast_frfree(f);
02224                f = &chan->dtmff;
02225                f->frametype = AST_FRAME_DTMF_END;
02226                f->subclass = chan->emulate_dtmf_digit;
02227                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02228                chan->dtmf_tv = now;
02229                if (chan->audiohooks) {
02230                   struct ast_frame *old_frame = f;
02231                   f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02232                   if (old_frame != f)
02233                      ast_frfree(old_frame);
02234                }
02235                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
02236             } else {
02237                /* Drop voice frames while we're still in the middle of the digit */
02238                ast_frfree(f);
02239                f = &ast_null_frame;
02240             }
02241          } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass & chan->nativeformats)) {
02242             /* This frame can't be from the current native formats -- drop it on the
02243                floor */
02244             ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
02245                chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
02246             ast_frame_dump(chan->name, f, "<<");
02247             ast_frfree(f);
02248             f = &ast_null_frame;
02249          } else if ((f->frametype == AST_FRAME_VOICE)) {
02250             if (chan->audiohooks) {
02251                struct ast_frame *old_frame = f;
02252                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02253                if (old_frame != f)
02254                   ast_frfree(old_frame);
02255             }
02256             if (chan->monitor && chan->monitor->read_stream ) {
02257                /* XXX what does this do ? */
02258 #ifndef MONITOR_CONSTANT_DELAY
02259                int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
02260                if (jump >= 0) {
02261                   jump = chan->outsmpl - chan->insmpl;
02262                   if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
02263                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
02264                   chan->insmpl += jump + f->samples;
02265                } else
02266                   chan->insmpl+= f->samples;
02267 #else
02268                int jump = chan->outsmpl - chan->insmpl;
02269                if (jump - MONITOR_DELAY >= 0) {
02270                   if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02271                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
02272                   chan->insmpl += jump;
02273                } else
02274                   chan->insmpl += f->samples;
02275 #endif
02276                if (chan->monitor->state == AST_MONITOR_RUNNING) {
02277                   if (ast_writestream(chan->monitor->read_stream, f) < 0)
02278                      ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
02279                }
02280             }
02281 
02282             if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL)
02283                f = &ast_null_frame;
02284 
02285             /* Run generator sitting on the line if timing device not available
02286             * and synchronous generation of outgoing frames is necessary       */
02287             ast_read_generator_actions(chan, f);
02288          }
02289       default:
02290          /* Just pass it on! */
02291          break;
02292       }
02293    } else {
02294       /* Make sure we always return NULL in the future */
02295       chan->_softhangup |= AST_SOFTHANGUP_DEV;
02296       if (chan->generator)
02297          ast_deactivate_generator(chan);
02298       /* End the CDR if appropriate */
02299       if (chan->cdr)
02300          ast_cdr_end(chan->cdr);
02301    }
02302 
02303    /* High bit prints debugging */
02304    if (chan->fin & DEBUGCHAN_FLAG)
02305       ast_frame_dump(chan->name, f, "<<");
02306    chan->fin = FRAMECOUNT_INC(chan->fin);
02307 
02308 done:
02309    ast_channel_unlock(chan);
02310    return f;
02311 }

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

References ast_channel::_state, outgoing_helper::account, ast_call(), AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CAUSE_NO_ANSWER, ast_cdr_alloc(), ast_cdr_disposition(), ast_cdr_end(), ast_cdr_failed(), ast_cdr_init(), ast_cdr_setaccount(), ast_cdr_setapp(), ast_cdr_start(), ast_cdr_update(), ast_channel_inherit_variables(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, 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().

02824 {
02825    int dummy_outstate;
02826    int cause = 0;
02827    struct ast_channel *chan;
02828    int res = 0;
02829    int last_subclass = 0;
02830    
02831    if (outstate)
02832       *outstate = 0;
02833    else
02834       outstate = &dummy_outstate;   /* make outstate always a valid pointer */
02835 
02836    chan = ast_request(type, format, data, &cause);
02837    if (!chan) {
02838       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
02839       /* compute error and return */
02840       if (cause == AST_CAUSE_BUSY)
02841          *outstate = AST_CONTROL_BUSY;
02842       else if (cause == AST_CAUSE_CONGESTION)
02843          *outstate = AST_CONTROL_CONGESTION;
02844       return NULL;
02845    }
02846 
02847    if (oh) {
02848       if (oh->vars)  
02849          ast_set_variables(chan, oh->vars);
02850       /* XXX why is this necessary, for the parent_channel perhaps ? */
02851       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
02852          ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
02853       if (oh->parent_channel)
02854          ast_channel_inherit_variables(oh->parent_channel, chan);
02855       if (oh->account)
02856          ast_cdr_setaccount(chan, oh->account); 
02857    }
02858    ast_set_callerid(chan, cid_num, cid_name, cid_num);
02859 
02860    
02861 
02862    if (!chan->cdr) { /* up till now, this insertion hasn't been done. Therefore,
02863             to keep from throwing off the basic order of the universe,
02864             we will try to keep this cdr from getting posted. */
02865       chan->cdr = ast_cdr_alloc();
02866       ast_cdr_init(chan->cdr, chan);
02867       ast_cdr_start(chan->cdr);
02868    }
02869    if (ast_call(chan, data, 0)) {   /* ast_call failed... */
02870       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
02871    } else {
02872       res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
02873       while (timeout && chan->_state != AST_STATE_UP) {
02874          struct ast_frame *f;
02875          res = ast_waitfor(chan, timeout);
02876          if (res <= 0) /* error, timeout, or done */
02877             break;
02878          if (timeout > -1)
02879             timeout = res;
02880          f = ast_read(chan);
02881          if (!f) {
02882             *outstate = AST_CONTROL_HANGUP;
02883             res = 0;
02884             break;
02885          }
02886          if (f->frametype == AST_FRAME_CONTROL) {
02887             switch (f->subclass) {
02888             case AST_CONTROL_RINGING:  /* record but keep going */
02889                *outstate = f->subclass;
02890                break;
02891 
02892             case AST_CONTROL_BUSY:
02893             case AST_CONTROL_CONGESTION:
02894             case AST_CONTROL_ANSWER:
02895                *outstate = f->subclass;
02896                timeout = 0;      /* trick to force exit from the while() */
02897                break;
02898 
02899             /* Ignore these */
02900             case AST_CONTROL_PROGRESS:
02901             case AST_CONTROL_PROCEEDING:
02902             case AST_CONTROL_HOLD:
02903             case AST_CONTROL_UNHOLD:
02904             case AST_CONTROL_VIDUPDATE:
02905             case AST_CONTROL_SRCUPDATE:
02906             case -1:       /* Ignore -- just stopping indications */
02907                break;
02908 
02909             default:
02910                ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
02911             }
02912             last_subclass = f->subclass;
02913          }
02914          ast_frfree(f);
02915       }
02916    }
02917 
02918    /* Final fixups */
02919    if (oh) {
02920       if (!ast_strlen_zero(oh->context))
02921          ast_copy_string(chan->context, oh->context, sizeof(chan->context));
02922       if (!ast_strlen_zero(oh->exten))
02923          ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
02924       if (oh->priority) 
02925          chan->priority = oh->priority;
02926    }
02927    if (chan->_state == AST_STATE_UP)
02928       *outstate = AST_CONTROL_ANSWER;
02929 
02930    if (res <= 0) {
02931       if ( AST_CONTROL_RINGING == last_subclass ) 
02932          chan->hangupcause = AST_CAUSE_NO_ANSWER;
02933       if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
02934          ast_cdr_init(chan->cdr, chan);
02935       if (chan->cdr) {
02936          char tmp[256];
02937          snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
02938          ast_cdr_setapp(chan->cdr,"Dial",tmp);
02939          ast_cdr_update(chan);
02940          ast_cdr_start(chan->cdr);
02941          ast_cdr_end(chan->cdr);
02942          /* If the cause wasn't handled properly */
02943          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
02944             ast_cdr_failed(chan->cdr);
02945       }
02946       ast_hangup(chan);
02947       chan = NULL;
02948    }
02949    return chan;
02950 }

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

Activate a given generator

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

01588 {
01589    int res = 0;
01590 
01591    ast_channel_lock(chan);
01592 
01593    if (chan->generatordata) {
01594       if (chan->generator && chan->generator->release)
01595          chan->generator->release(chan, chan->generatordata);
01596       chan->generatordata = NULL;
01597    }
01598 
01599    ast_prod(chan);
01600    if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
01601       res = -1;
01602    }
01603    
01604    if (!res) {
01605       ast_settimeout(chan, 160, generator_force, chan);
01606       chan->generator = gen;
01607    }
01608 
01609    ast_channel_unlock(chan);
01610 
01611    return res;
01612 }

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns number of active/allocated channels

Definition at line 442 of file channel.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and channels.

Referenced by quit_handler().

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

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

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

Referenced by __login_exec(), action_bridge(), agi_exec_full(), alarmreceiver_exec(), app_exec(), ast_bridge_call(), ast_control_streamfile(), ast_pickup_call(), auth_exec(), background_detect_exec(), bridge_exec(), builtin_parkcall(), common_exec(), conf_exec(), count_exec(), dictate_exec(), directory_exec(), disa_exec(), features_answer(), handle_answer(), ices_exec(), milliwatt_exec(), mwanalyze_exec(), nv_background_detect_exec(), nv_detectfax_exec(), park_call_exec(), park_exec(), pbx_builtin_answer(), pbx_builtin_background(), pickup_channel(), pickup_do(), playback_exec(), privacy_exec(), read_exec(), run_station(), rxfax_exec(), sayunixtime_exec(), send_waveform_to_channel(), skel_exec(), sla_handle_dial_state_event(), sla_station_exec(), speech_background(), steal_channel(), testclient_exec(), testserver_exec(), txfax_exec(), vm_exec(), vm_execmain(), waitforsilence_exec(), zapateller_exec(), and zapras_exec().

01509 {
01510    int res = 0;
01511    ast_channel_lock(chan);
01512    /* You can't answer an outbound call */
01513    if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
01514       ast_channel_unlock(chan);
01515       return 0;
01516    }
01517    /* Stop if we're a zombie or need a soft hangup */
01518    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01519       ast_channel_unlock(chan);
01520       return -1;
01521    }
01522    switch(chan->_state) {
01523    case AST_STATE_RINGING:
01524    case AST_STATE_RING:
01525       if (chan->tech->answer)
01526          res = chan->tech->answer(chan);
01527       ast_setstate(chan, AST_STATE_UP);
01528       ast_cdr_answer(chan->cdr);
01529       break;
01530    case AST_STATE_UP:
01531       ast_cdr_answer(chan->cdr);
01532       break;
01533    default:
01534       break;
01535    }
01536    chan->visible_indication = 0;
01537    ast_channel_unlock(chan);
01538    return res;
01539 }

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

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

Referenced by quit_handler().

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

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

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

struct ast_channel* ast_bridged_channel ( struct ast_channel chan  ) 

Find bridged channel.

Parameters:
chan Current channel

Definition at line 3662 of file channel.c.

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

Referenced by __zt_exception(), action_agents(), 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().

03663 {
03664    struct ast_channel *bridged;
03665    bridged = chan->_bridge;
03666    if (bridged && bridged->tech->bridged_channel)
03667       bridged = bridged->tech->bridged_channel(chan, bridged);
03668    return bridged;
03669 }

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

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

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

03008 {
03009    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
03010       If the remote end does not answer within the timeout, then do NOT hang up, but
03011       return anyway.  */
03012    int res = -1;
03013    /* Stop if we're a zombie or need a soft hangup */
03014    ast_channel_lock(chan);
03015    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03016       if (chan->tech->call)
03017          res = chan->tech->call(chan, addr, timeout);
03018       ast_set_flag(chan, AST_FLAG_OUTGOING);
03019    }
03020    ast_channel_unlock(chan);
03021    return res;
03022 }

void ast_cancel_shutdown ( void   ) 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 454 of file channel.c.

Referenced by handle_abort_halt().

00455 {
00456    shutting_down = 0;
00457 }

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

References causes, and desc.

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

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

void ast_change_name ( struct ast_channel chan,
char *  newname 
)

Change channel name.

Definition at line 3255 of file channel.c.

References ast_string_field_set, manager_event(), and name.

03256 {
03257    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
03258    ast_string_field_set(chan, name, newname);
03259 }

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 708 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 sched_context_destroy().

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

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

References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_CONTROL_SRCUPDATE, AST_FEATURE_PLAY_WARNING, AST_FEATURE_REDIRECT, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_generic_bridge(), ast_indicate(), ast_log(), ast_set_flag, AST_SOFTHANGUP_UNBRIDGE, ast_strlen_zero(), ast_test_flag, ast_tvadd(), ast_tvsub(), ast_verbose(), ast_channel::audiohooks, ast_channel_tech::bridge, bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, config, ast_channel::generator, LOG_DEBUG, manager_event(), ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::nativeformats, option_debug, option_verbose, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), ast_channel::readformat, ast_channel_tech::send_digit_begin, t, ast_channel::tech, VERBOSE_PREFIX_3, and ast_channel::writeformat.

Referenced by ast_bridge_call().

03854 {
03855    struct ast_channel *who = NULL;
03856    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03857    int nativefailed=0;
03858    int firstpass;
03859    int o0nativeformats;
03860    int o1nativeformats;
03861    long time_left_ms=0;
03862    struct timeval nexteventts = { 0, };
03863    char caller_warning = 0;
03864    char callee_warning = 0;
03865 
03866    if (c0->_bridge) {
03867       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
03868          c0->name, c0->_bridge->name);
03869       return -1;
03870    }
03871    if (c1->_bridge) {
03872       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
03873          c1->name, c1->_bridge->name);
03874       return -1;
03875    }
03876    
03877    /* Stop if we're a zombie or need a soft hangup */
03878    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
03879        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
03880       return -1;
03881 
03882    *fo = NULL;
03883    firstpass = config->firstpass;
03884    config->firstpass = 0;
03885 
03886    if (ast_tvzero(config->start_time))
03887       config->start_time = ast_tvnow();
03888    time_left_ms = config->timelimit;
03889 
03890    caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
03891    callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
03892 
03893    if (config->start_sound && firstpass) {
03894       if (caller_warning)
03895          bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000);
03896       if (callee_warning)
03897          bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000);
03898    }
03899 
03900    /* Keep track of bridge */
03901    c0->_bridge = c1;
03902    c1->_bridge = c0;
03903 
03904    /* \todo  XXX here should check that cid_num is not NULL */
03905    manager_event(EVENT_FLAG_CALL, "Link",
03906             "Channel1: %s\r\n"
03907             "Channel2: %s\r\n"
03908             "Uniqueid1: %s\r\n"
03909             "Uniqueid2: %s\r\n"
03910             "CallerID1: %s\r\n"
03911             "CallerID2: %s\r\n",
03912             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03913 
03914    o0nativeformats = c0->nativeformats;
03915    o1nativeformats = c1->nativeformats;
03916 
03917    if (config->feature_timer) {
03918       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
03919    } else if (config->timelimit) {
03920       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
03921       if (caller_warning || callee_warning)
03922          nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000));
03923    }
03924 
03925    if (!c0->tech->send_digit_begin)
03926       ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
03927    if (!c1->tech->send_digit_begin)
03928       ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
03929 
03930    /* Before we enter in and bridge these two together tell them both the source of audio has changed */
03931    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
03932    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
03933 
03934    for (/* ever */;;) {
03935       struct timeval now = { 0, };
03936       int to;
03937 
03938       to = -1;
03939 
03940       if (!ast_tvzero(nexteventts)) {
03941          now = ast_tvnow();
03942          to = ast_tvdiff_ms(nexteventts, now);
03943          if (to <= 0) {
03944             if (!config->timelimit) {
03945                res = AST_BRIDGE_COMPLETE;
03946                break;
03947             }
03948             to = 0;
03949          }
03950       }
03951 
03952       if (config->timelimit) {
03953          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
03954          if (time_left_ms < to)
03955             to = time_left_ms;
03956 
03957          if (time_left_ms <= 0) {
03958             if (caller_warning && config->end_sound)
03959                bridge_playfile(c0, c1, config->end_sound, 0);
03960             if (callee_warning && config->end_sound)
03961                bridge_playfile(c1, c0, config->end_sound, 0);
03962             *fo = NULL;
03963             if (who)
03964                *rc = who;
03965             res = 0;
03966             break;
03967          }
03968          
03969          if (!to) {
03970             if (time_left_ms >= 5000 && config->warning_sound && config->play_warning) {
03971                int t = (time_left_ms + 500) / 1000; /* round to nearest second */
03972                if (caller_warning)
03973                   bridge_playfile(c0, c1, config->warning_sound, t);
03974                if (callee_warning)
03975                   bridge_playfile(c1, c0, config->warning_sound, t);
03976             }
03977             if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000)))
03978                nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
03979             else
03980                nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
03981          }
03982       }
03983 
03984       if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
03985          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03986             c0->_softhangup = 0;
03987          if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03988             c1->_softhangup = 0;
03989          c0->_bridge = c1;
03990          c1->_bridge = c0;
03991          if (option_debug)
03992             ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
03993          continue;
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          *fo = NULL;
04000          if (who)
04001             *rc = who;
04002          res = 0;
04003          if (option_debug)
04004             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",
04005                c0->name, c1->name,
04006                ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
04007                ast_check_hangup(c0) ? "Yes" : "No",
04008                ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
04009                ast_check_hangup(c1) ? "Yes" : "No");
04010          break;
04011       }
04012       
04013       /* See if the BRIDGEPEER variable needs to be updated */
04014       if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER")))
04015          pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1->name);
04016       if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER")))
04017          pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0->name);
04018       
04019       if (c0->tech->bridge &&
04020           (config->timelimit == 0) &&
04021           (c0->tech->bridge == c1->tech->bridge) &&
04022           !nativefailed && !c0->monitor && !c1->monitor &&
04023           !c0->audiohooks && !c1->audiohooks && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) &&
04024           !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) &&
04025           !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
04026          /* Looks like they share a bridge method and nothing else is in the way */
04027          ast_set_flag(c0, AST_FLAG_NBRIDGE);
04028          ast_set_flag(c1, AST_FLAG_NBRIDGE);
04029          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
04030             /* \todo  XXX here should check that cid_num is not NULL */
04031             manager_event(EVENT_FLAG_CALL, "Unlink",
04032                      "Channel1: %s\r\n"
04033                      "Channel2: %s\r\n"
04034                      "Uniqueid1: %s\r\n"
04035                      "Uniqueid2: %s\r\n"
04036                      "CallerID1: %s\r\n"
04037                      "CallerID2: %s\r\n",
04038                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04039             if (option_debug)
04040                ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
04041 
04042             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
04043             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
04044 
04045             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04046                continue;
04047 
04048             c0->_bridge = NULL;
04049             c1->_bridge = NULL;
04050 
04051             return res;
04052          } else {
04053             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
04054             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
04055          }
04056          switch (res) {
04057          case AST_BRIDGE_RETRY:
04058             continue;
04059          default:
04060             if (option_verbose > 2)
04061                ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s ended\n",
04062                       c0->name, c1->name);
04063             /* fallthrough */
04064          case AST_BRIDGE_FAILED_NOWARN:
04065             nativefailed++;
04066             break;
04067          }
04068       }
04069    
04070       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
04071           (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
04072           !(c0->generator || c1->generator)) {
04073          if (ast_channel_make_compatible(c0, c1)) {
04074             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
04075             /* \todo  XXX here should check that cid_num is not NULL */
04076                                 manager_event(EVENT_FLAG_CALL, "Unlink",
04077                      "Channel1: %s\r\n"
04078                      "Channel2: %s\r\n"
04079                      "Uniqueid1: %s\r\n"
04080                      "Uniqueid2: %s\r\n"
04081                      "CallerID1: %s\r\n"
04082                      "CallerID2: %s\r\n",
04083                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04084             return AST_BRIDGE_FAILED;
04085          }
04086          o0nativeformats = c0->nativeformats;
04087          o1nativeformats = c1->nativeformats;
04088       }
04089       res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
04090       if (res != AST_BRIDGE_RETRY)
04091          break;
04092    }
04093 
04094    ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
04095    ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
04096 
04097    /* Now that we have broken the bridge the source will change yet again */
04098    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
04099    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
04100 
04101    c0->_bridge = NULL;
04102    c1->_bridge = NULL;
04103 
04104    /* \todo  XXX here should check that cid_num is not NULL */
04105    manager_event(EVENT_FLAG_CALL, "Unlink",
04106             "Channel1: %s\r\n"
04107             "Channel2: %s\r\n"
04108             "Uniqueid1: %s\r\n"
04109             "Uniqueid2: %s\r\n"
04110             "CallerID1: %s\r\n"
04111             "CallerID2: %s\r\n",
04112             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04113    if (option_debug)
04114       ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
04115 
04116    return res;
04117 }

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

References ast_channel::whentohangup.

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

int ast_channel_datastore_add ( struct ast_channel chan,
struct ast_datastore datastore 
)

Add a datastore to a channel.

Definition at line 1326 of file channel.c.

References AST_LIST_INSERT_HEAD.

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

01327 {
01328    int res = 0;
01329 
01330    AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
01331 
01332    return res;
01333 }

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

Create a channel datastore structure.

Definition at line 1265 of file channel.c.

References ast_calloc, ast_strdup, and ast_datastore::info.

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

01266 {
01267    struct ast_datastore *datastore = NULL;
01268 
01269    /* Make sure we at least have type so we can identify this */
01270    if (info == NULL) {
01271       return NULL;
01272    }
01273 
01274    /* Allocate memory for datastore and clear it */
01275    datastore = ast_calloc(1, sizeof(*datastore));
01276    if (datastore == NULL) {
01277       return NULL;
01278    }
01279 
01280    datastore->info = info;
01281 
01282    datastore->uid = ast_strdup(uid);
01283 
01284    return datastore;
01285 }

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

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

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

01354 {
01355    struct ast_datastore *datastore = NULL;
01356    
01357    if (info == NULL)
01358       return NULL;
01359 
01360    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
01361       if (datastore->info == info) {
01362          if (uid != NULL && datastore->uid != NULL) {
01363             if (!strcasecmp(uid, datastore->uid)) {
01364                /* Matched by type AND uid */
01365                break;
01366             }
01367          } else {
01368             /* Matched by type at least */
01369             break;
01370          }
01371       }
01372    }
01373    AST_LIST_TRAVERSE_SAFE_END
01374 
01375    return datastore;
01376 }

int ast_channel_datastore_free ( struct ast_datastore datastore  ) 

Free a channel datastore structure.

Definition at line 1287 of file channel.c.

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

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

01288 {
01289    int res = 0;
01290 
01291    /* Using the destroy function (if present) destroy the data */
01292    if (datastore->info->destroy != NULL && datastore->data != NULL) {
01293       datastore->info->destroy(datastore->data);
01294       datastore->data = NULL;
01295    }
01296 
01297    /* Free allocated UID memory */
01298    if (datastore->uid != NULL) {
01299       free(datastore->uid);
01300       datastore->uid = NULL;
01301    }
01302 
01303    /* Finally free memory used by ourselves */
01304    free(datastore);
01305 
01306    return res;
01307 }

int ast_channel_datastore_inherit ( struct ast_channel from,
struct ast_channel to 
)

Inherit datastores from a parent to a child.

Definition at line 1309 of file channel.c.

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

Referenced by local_call(), and wait_for_answer().

01310 {
01311    struct ast_datastore *datastore = NULL, *datastore2;
01312 
01313    AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
01314       if (datastore->inheritance > 0) {
01315          datastore2 = ast_channel_datastore_alloc(datastore->info, datastore->uid);
01316          if (datastore2) {
01317             datastore2->data = datastore->info->duplicate(datastore->data);
01318             datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
01319             AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
01320          }
01321       }
01322    }
01323    return 0;
01324 }

int ast_channel_datastore_remove ( struct ast_channel chan,
struct ast_datastore datastore 
)

Remove a datastore from a channel.

Definition at line 1335 of file channel.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, and AST_LIST_TRAVERSE_SAFE_END.

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

01336 {
01337    struct ast_datastore *datastore2 = NULL;
01338    int res = -1;
01339 
01340    /* Find our position and remove ourselves */
01341    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, entry) {
01342       if (datastore2 == datastore) {
01343          AST_LIST_REMOVE_CURRENT(&chan->datastores, entry);
01344          res = 0;
01345          break;
01346       }
01347    }
01348    AST_LIST_TRAVERSE_SAFE_END
01349 
01350    return res;
01351 }

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

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

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

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

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

03262 {
03263    struct ast_var_t *current, *newvar;
03264    const char *varname;
03265 
03266    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
03267       int vartype = 0;
03268 
03269       varname = ast_var_full_name(current);
03270       if (!varname)
03271          continue;
03272 
03273       if (varname[0] == '_') {
03274          vartype = 1;
03275          if (varname[1] == '_')
03276             vartype = 2;
03277       }
03278 
03279       switch (vartype) {
03280       case 1:
03281          newvar = ast_var_assign(&varname[1], ast_var_value(current));
03282          if (newvar) {
03283             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03284             if (option_debug)
03285                ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
03286          }
03287          break;
03288       case 2:
03289          newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
03290          if (newvar) {
03291             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03292             if (option_debug)
03293                ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
03294          }
03295          break;
03296       default:
03297          if (option_debug)
03298             ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
03299          break;
03300       }
03301    }
03302 }

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 3114 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(), ast_channel::nativeformats, ast_channel::readformat, and ast_channel::writeformat.

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

03115 {
03116    int src;
03117    int dst;
03118 
03119    if (chan->readformat == peer->writeformat && chan->writeformat == peer->readformat) {
03120       /* Already compatible!  Moving on ... */
03121       return 0;
03122    }
03123 
03124    /* Set up translation from the chan to the peer */
03125    src = chan->nativeformats;
03126    dst = peer->nativeformats;
03127    if (ast_translator_best_choice(&dst, &src) < 0) {
03128       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
03129       return -1;
03130    }
03131 
03132    /* if the best path is not 'pass through', then
03133       transcoding is needed; if desired, force transcode path
03134       to use SLINEAR between channels, but only if there is
03135       no direct conversion available */
03136    if ((src != dst) && ast_opt_transcode_via_slin &&
03137        (ast_translate_path_steps(dst, src) != 1))
03138       dst = AST_FORMAT_SLINEAR;
03139    if (ast_set_read_format(chan, dst) < 0) {
03140       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
03141       return -1;
03142    }
03143    if (ast_set_write_format(peer, dst) < 0) {
03144       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst);
03145       return -1;
03146    }
03147 
03148    /* Set up translation from the peer to the chan */
03149    src = peer->nativeformats;
03150    dst = chan->nativeformats;
03151    if (ast_translator_best_choice(&dst, &src) < 0) {
03152       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst);
03153       return -1;
03154    }
03155 
03156    /* if the best path is not 'pass through', then
03157       transcoding is needed; if desired, force transcode path
03158       to use SLINEAR between channels, but only if there is
03159       no direct conversion available */
03160    if ((src != dst) && ast_opt_transcode_via_slin &&
03161        (ast_translate_path_steps(dst, src) != 1))
03162       dst = AST_FORMAT_SLINEAR;
03163    if (ast_set_read_format(peer, dst) < 0) {
03164       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst);
03165       return -1;
03166    }
03167    if (ast_set_write_format(chan, dst) < 0) {
03168       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst);
03169       return -1;
03170    }
03171    return 0;
03172 }

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

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

Referenced by ast_async_goto(), ast_masq_park_call(), ast_pickup_call(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), misdn_transfer_bc(), pickup_channel(), pickup_do(), sip_park(), and steal_channel().

03175 {
03176    int res = -1;
03177    struct ast_channel *final_orig, *final_clone, *base;
03178 
03179 retrymasq:
03180    final_orig = original;
03181    final_clone = clone;
03182 
03183    ast_channel_lock(original);
03184    while (ast_channel_trylock(clone)) {
03185       ast_channel_unlock(original);
03186       usleep(1);
03187       ast_channel_lock(original);
03188    }
03189 
03190    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
03191       and if so, we don't really want to masquerade it, but its proxy */
03192    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
03193       final_orig = original->_bridge;
03194 
03195    if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone))
03196       final_clone = clone->_bridge;
03197    
03198    if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) {
03199       final_clone = base;
03200    }
03201 
03202    if ((final_orig != original) || (final_clone != clone)) {
03203       /* Lots and lots of deadlock avoidance.  The main one we're competing with
03204        * is ast_write(), which locks channels recursively, when working with a
03205        * proxy channel. */
03206       if (ast_channel_trylock(final_orig)) {
03207          ast_channel_unlock(clone);
03208          ast_channel_unlock(original);
03209          goto retrymasq;
03210       }
03211       if (ast_channel_trylock(final_clone)) {
03212          ast_channel_unlock(final_orig);
03213          ast_channel_unlock(clone);
03214          ast_channel_unlock(original);
03215          goto retrymasq;
03216       }
03217       ast_channel_unlock(clone);
03218       ast_channel_unlock(original);
03219       original = final_orig;
03220       clone = final_clone;
03221    }
03222 
03223    if (original == clone) {
03224       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
03225       ast_channel_unlock(clone);
03226       ast_channel_unlock(original);
03227       return -1;
03228    }
03229 
03230    if (option_debug)
03231       ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
03232          clone->name, original->name);
03233    if (original->masq) {
03234       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03235          original->masq->name, original->name);
03236    } else if (clone->masqr) {
03237       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03238          clone->name, clone->masqr->name);
03239    } else {
03240       original->masq = clone;
03241       clone->masqr = original;
03242       ast_queue_frame(original, &ast_null_frame);
03243       ast_queue_frame(clone, &ast_null_frame);
03244       if (option_debug)
03245          ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
03246       res = 0;
03247    }
03248 
03249    ast_channel_unlock(clone);
03250    ast_channel_unlock(original);
03251 
03252    return res;
03253 }

char* ast_channel_reason2str ( int  reason  ) 

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

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

Definition at line 2800 of file channel.c.

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

Referenced by attempt_thread().

02801 {
02802    switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */
02803    {
02804    case 0:
02805       return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
02806    case AST_CONTROL_HANGUP:
02807       return "Hangup";
02808    case AST_CONTROL_RING:
02809       return "Local Ring";
02810    case AST_CONTROL_RINGING:
02811       return "Remote end Ringing";
02812    case AST_CONTROL_ANSWER:
02813       return "Remote end has Answered";
02814    case AST_CONTROL_BUSY:
02815       return "Remote end is Busy";
02816    case AST_CONTROL_CONGESTION:
02817       return "Congestion (circuits busy)";
02818    default:
02819       return "Unknown Reason!!";
02820    }
02821 }

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

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

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

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

03103 {
03104    if (chan->tech->send_html)
03105       return chan->tech->send_html(chan, subclass, data, datalen);
03106    return -1;
03107 }

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

References ast_channel_sendhtml(), and AST_HTML_URL.

Referenced by sendurl_exec(), and try_calling().

03110 {
03111    return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
03112 }

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

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

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

04121 {
04122    int res;
04123 
04124    if (chan->tech->setoption) {
04125       res = chan->tech->setoption(chan, option, data, datalen);
04126       if (res < 0)
04127          return res;
04128    } else {
04129       errno = ENOSYS;
04130       return -1;
04131    }
04132    if (block) {
04133       /* XXX Implement blocking -- just wait for our option frame reply, discarding
04134          intermediate packets. XXX */
04135       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
04136       return -1;
04137    }
04138    return 0;
04139 }

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

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

Referenced by action_timeout(), and timeout_write().

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

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

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

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

04449 {
04450    struct ast_silence_generator *state;
04451 
04452    if (!(state = ast_calloc(1, sizeof(*state)))) {
04453       return NULL;
04454    }
04455 
04456    state->old_write_format = chan->writeformat;
04457 
04458    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
04459       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
04460       free(state);
04461       return NULL;
04462    }
04463 
04464    ast_activate_generator(chan, &silence_generator, state);
04465 
04466    if (option_debug)
04467       ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
04468 
04469    return state;
04470 }

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

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

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

04473 {
04474    if (!state)
04475       return;
04476 
04477    ast_deactivate_generator(chan);
04478 
04479    if (option_debug)
04480       ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
04481 
04482    if (ast_set_write_format(chan, state->old_write_format) < 0)
04483       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
04484 
04485    free(state);
04486 }

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

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

Referenced by sendurl_exec(), and try_calling().

03098 {
03099    return (chan->tech->send_html) ? 1 : 0;
03100 }

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

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

Referenced by __unload_module(), and unload_module().

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

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

References channel_find_locked().

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

01100 {
01101    return channel_find_locked(prev, NULL, 0, NULL, NULL);
01102 }

void ast_channels_init ( void   ) 

Provided by channel.c

Definition at line 4372 of file channel.c.

References ast_cli_register_multiple(), and cli_channel.

Referenced by main().

04373 {
04374    ast_cli_register_multiple(cli_channel, sizeof(cli_channel) / sizeof(struct ast_cli_entry));
04375 }

struct ast_variable* ast_channeltype_list ( void   ) 

return an ast_variable list of channeltypes

Definition at line 162 of file channel.c.

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

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

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

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

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

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

static int ast_check_hangup_locked ( struct ast_channel chan  )  [static]

Definition at line 398 of file channel.c.

References ast_channel_lock, ast_channel_unlock, and ast_check_hangup().

Referenced by ast_channel_bridge().

00399 {
00400    int res;
00401    ast_channel_lock(chan);
00402    res = ast_check_hangup(chan);
00403    ast_channel_unlock(chan);
00404    return res;
00405 }

void ast_deactivate_generator ( struct ast_channel chan  ) 

Deactive an active generator

Definition at line 1541 of file channel.c.

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

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

01542 {
01543    ast_channel_lock(chan);
01544    if (chan->generatordata) {
01545       if (chan->generator && chan->generator->release)
01546          chan->generator->release(chan, chan->generatordata);
01547       chan->generatordata = NULL;
01548       chan->generator = NULL;
01549       chan->fds[AST_GENERATOR_FD] = -1;
01550       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
01551       ast_settimeout(chan, 0, NULL, NULL);
01552    }
01553    ast_channel_unlock(chan);
01554 }

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

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

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

03336 {
03337    int x,i;
03338    int res=0;
03339    int origstate;
03340    struct ast_frame *cur;
03341    const struct ast_channel_tech *t;
03342    void *t_pvt;
03343    struct ast_callerid tmpcid;
03344    struct ast_channel *clone = original->masq;
03345    struct ast_cdr *cdr;
03346    int rformat = original->readformat;
03347    int wformat = original->writeformat;
03348    char newn[100];
03349    char orig[100];
03350    char masqn[100];
03351    char zombn[100];
03352 
03353    if (option_debug > 3)
03354       ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
03355          clone->name, clone->_state, original->name, original->_state);
03356 
03357    /* XXX This is a seriously wacked out operation.  We're essentially putting the guts of
03358       the clone channel into the original channel.  Start by killing off the original
03359       channel's backend.   I'm not sure we're going to keep this function, because
03360       while the features are nice, the cost is very high in terms of pure nastiness. XXX */
03361 
03362    /* We need the clone's lock, too */
03363    ast_channel_lock(clone);
03364 
03365    if (option_debug > 1)
03366       ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock);
03367 
03368    /* Having remembered the original read/write formats, we turn off any translation on either
03369       one */
03370    free_translation(clone);
03371    free_translation(original);
03372 
03373 
03374    /* Unlink the masquerade */
03375    original->masq = NULL;
03376    clone->masqr = NULL;
03377    
03378    /* Save the original name */
03379    ast_copy_string(orig, original->name, sizeof(orig));
03380    /* Save the new name */
03381    ast_copy_string(newn, clone->name, sizeof(newn));
03382    /* Create the masq name */
03383    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
03384       
03385    /* Copy the name from the clone channel */
03386    ast_string_field_set(original, name, newn);
03387 
03388    /* Mangle the name of the clone channel */
03389    ast_string_field_set(clone, name, masqn);
03390    
03391    /* Notify any managers of the change, first the masq then the other */
03392    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
03393    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
03394 
03395    /* Swap the technologies */   
03396    t = original->tech;
03397    original->tech = clone->tech;
03398    clone->tech = t;
03399 
03400    /* Swap the cdrs */
03401    cdr = original->cdr;
03402    original->cdr = clone->cdr;
03403    clone->cdr = cdr;
03404 
03405    t_pvt = original->tech_pvt;
03406    original->tech_pvt = clone->tech_pvt;
03407    clone->tech_pvt = t_pvt;
03408 
03409    /* Swap the alertpipes */
03410    for (i = 0; i < 2; i++) {
03411       x = original->alertpipe[i];
03412       original->alertpipe[i] = clone->alertpipe[i];
03413       clone->alertpipe[i] = x;
03414    }
03415 
03416    /* 
03417     * Swap the readq's.  The end result should be this:
03418     *
03419     *  1) All frames should be on the new (original) channel.
03420     *  2) Any frames that were already on the new channel before this
03421     *     masquerade need to be at the end of the readq, after all of the
03422     *     frames on the old (clone) channel.
03423     *  3) The alertpipe needs to get poked for every frame that was already
03424     *     on the new channel, since we are now using the alert pipe from the
03425     *     old (clone) channel.
03426     */
03427    {
03428       AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
03429       AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
03430 
03431       AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
03432       AST_LIST_APPEND_LIST(&original->readq, &clone->readq, frame_list);
03433 
03434       while ((cur = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
03435          AST_LIST_INSERT_TAIL(&original->readq, cur, frame_list);
03436          if (original->alertpipe[1] > -1) {
03437             int poke = 0;
03438             write(original->alertpipe[1], &poke, sizeof(poke));
03439          }
03440       }
03441    }
03442 
03443    /* Swap the raw formats */
03444    x = original->rawreadformat;
03445    original->rawreadformat = clone->rawreadformat;
03446    clone->rawreadformat = x;
03447    x = original->rawwriteformat;
03448    original->rawwriteformat = clone->rawwriteformat;
03449    clone->rawwriteformat = x;
03450 
03451    clone->_softhangup = AST_SOFTHANGUP_DEV;
03452 
03453    /* And of course, so does our current state.  Note we need not
03454       call ast_setstate since the event manager doesn't really consider
03455       these separate.  We do this early so that the clone has the proper
03456       state of the original channel. */
03457    origstate = original->_state;
03458    original->_state = clone->_state;
03459    clone->_state = origstate;
03460 
03461    if (clone->tech->fixup){
03462       res = clone->tech->fixup(original, clone);
03463       if (res)
03464          ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
03465    }
03466 
03467    /* Start by disconnecting the original's physical side */
03468    if (clone->tech->hangup)
03469       res = clone->tech->hangup(clone);
03470    if (res) {
03471       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
03472       ast_channel_unlock(clone);
03473       return -1;
03474    }
03475    
03476    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
03477    /* Mangle the name of the clone channel */
03478    ast_string_field_set(clone, name, zombn);
03479    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid);
03480 
03481    /* Update the type. */
03482    t_pvt = original->monitor;
03483    original->monitor = clone->monitor;
03484    clone->monitor = t_pvt;
03485    
03486    /* Keep the same language.  */
03487    ast_string_field_set(original, language, clone->language);
03488    /* Copy the FD's other than the generator fd */
03489    for (x = 0; x < AST_MAX_FDS; x++) {
03490       if (x != AST_GENERATOR_FD)
03491          original->fds[x] = clone->fds[x];
03492    }
03493 
03494    ast_app_group_update(clone, original);
03495    /* Move data stores over */
03496    if (AST_LIST_FIRST(&clone->datastores)) {
03497       struct ast_datastore *ds;
03498       AST_LIST_APPEND_LIST(&original->datastores, &clone->datastores, entry);
03499       AST_LIST_TRAVERSE(&original->datastores, ds, entry) {
03500          if (ds->info->chan_fixup)
03501             ds->info->chan_fixup(ds->data, clone, original);
03502       }
03503    }
03504 
03505    clone_variables(original, clone);
03506    /* Presense of ADSI capable CPE follows clone */
03507    original->adsicpe = clone->adsicpe;
03508    /* Bridge remains the same */
03509    /* CDR fields remain the same */
03510    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
03511    /* Application and data remain the same */
03512    /* Clone exception  becomes real one, as with fdno */
03513    ast_copy_flags(original, clone, AST_FLAG_EXCEPTION);
03514    original->fdno = clone->fdno;
03515    /* Schedule context remains the same */
03516    /* Stream stuff stays the same */
03517    /* Keep the original state.  The fixup code will need to work with it most likely */
03518 
03519    /* Just swap the whole structures, nevermind the allocations, they'll work themselves
03520       out. */
03521    tmpcid = original->cid;
03522    original->cid = clone->cid;
03523    clone->cid = tmpcid;
03524    
03525    /* Restore original timing file descriptor */
03526    original->fds[AST_TIMING_FD] = original->timingfd;
03527    
03528    /* Our native formats are different now */
03529    original->nativeformats = clone->nativeformats;
03530    
03531    /* Context, extension, priority, app data, jump table,  remain the same */
03532    /* pvt switches.  pbx stays the same, as does next */
03533    
03534    /* Set the write format */
03535    ast_set_write_format(original, wformat);
03536 
03537    /* Set the read format */
03538    ast_set_read_format(original, rformat);
03539 
03540    /* Copy the music class */
03541    ast_string_field_set(original, musicclass, clone->musicclass);
03542 
03543    if (option_debug)
03544       ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
03545 
03546    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
03547       can fix up everything as best as possible */
03548    if (original->tech->fixup) {
03549       res = original->tech->fixup(clone, original);
03550       if (res) {
03551          ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
03552             original->tech->type, original->name);
03553          ast_channel_unlock(clone);
03554          return -1;
03555       }
03556    } else
03557       ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
03558          original->tech->type, original->name);
03559 
03560    /* If an indication is currently playing maintain it on the channel that is taking the place of original */
03561    if (original->visible_indication)
03562       ast_indicate(original, original->visible_indication);
03563    
03564    /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
03565       a zombie so nothing tries to touch it.  If it's already been marked as a
03566       zombie, then free it now (since it already is considered invalid). */
03567    if (ast_test_flag(clone, AST_FLAG_ZOMBIE)) {
03568       if (option_debug)
03569          ast_log(LOG_DEBUG, "Destroying channel clone '%s'\n", clone->name);
03570       ast_channel_unlock(clone);
03571       manager_event(EVENT_FLAG_CALL, "Hangup",
03572          "Channel: %s\r\n"
03573          "Uniqueid: %s\r\n"
03574          "Cause: %d\r\n"
03575          "Cause-txt: %s\r\n",
03576          clone->name,
03577          clone->uniqueid,
03578          clone->hangupcause,
03579          ast_cause2str(clone->hangupcause)
03580          );
03581       ast_channel_free(clone);
03582    } else {
03583       if (option_debug)
03584          ast_log(LOG_DEBUG, "Released clone lock on '%s'\n", clone->name);
03585       ast_set_flag(clone, AST_FLAG_ZOMBIE);
03586       ast_queue_frame(clone, &ast_null_frame);
03587       ast_channel_unlock(clone);
03588    }
03589    
03590    /* Signal any blocker */
03591    if (ast_test_flag(original, AST_FLAG_BLOCKING))
03592       pthread_kill(original->blocker, SIGURG);
03593    if (option_debug)
03594       ast_log(LOG_DEBUG, "Done Masquerading %s (%d)\n", original->name, original->_state);
03595    return 0;
03596 }

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

03708 {
03709    /* Copy voice back and forth between the two channels. */
03710    struct ast_channel *cs[3];
03711    struct ast_frame *f;
03712    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03713    int o0nativeformats;
03714    int o1nativeformats;
03715    int watch_c0_dtmf;
03716    int watch_c1_dtmf;
03717    void *pvt0, *pvt1;
03718    /* Indicates whether a frame was queued into a jitterbuffer */
03719    int frame_put_in_jb = 0;
03720    int jb_in_use;
03721    int to;
03722    
03723    cs[0] = c0;
03724    cs[1] = c1;
03725    pvt0 = c0->tech_pvt;
03726    pvt1 = c1->tech_pvt;
03727    o0nativeformats = c0->nativeformats;
03728    o1nativeformats = c1->nativeformats;
03729    watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
03730    watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
03731 
03732    /* Check the need of a jitterbuffer for each channel */
03733    jb_in_use = ast_jb_do_usecheck(c0, c1);
03734 
03735    for (;;) {
03736       struct ast_channel *who, *other;
03737 
03738       if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
03739           (o0nativeformats != c0->nativeformats) ||
03740           (o1nativeformats != c1->nativeformats)) {
03741          /* Check for Masquerade, codec changes, etc */
03742          res = AST_BRIDGE_RETRY;
03743          break;
03744       }
03745       if (bridge_end.tv_sec) {
03746          to = ast_tvdiff_ms(bridge_end, ast_tvnow());
03747          if (to <= 0) {
03748             if (config->timelimit)
03749                res = AST_BRIDGE_RETRY;
03750             else
03751                res = AST_BRIDGE_COMPLETE;
03752             break;
03753          }
03754       } else
03755          to = -1;
03756       /* Calculate the appropriate max sleep interval - in general, this is the time,
03757          left to the closest jb delivery moment */
03758       if (jb_in_use)
03759          to = ast_jb_get_when_to_wakeup(c0, c1, to);
03760       who = ast_waitfor_n(cs, 2, &to);
03761       if (!who) {
03762          /* No frame received within the specified timeout - check if we have to deliver now */
03763          if (jb_in_use)
03764             ast_jb_get_and_deliver(c0, c1);
03765          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
03766             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03767                c0->_softhangup = 0;
03768             if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03769                c1->_softhangup = 0;
03770             c0->_bridge = c1;
03771             c1->_bridge = c0;
03772          }
03773          continue;
03774       }
03775       f = ast_read(who);
03776       if (!f) {
03777          *fo = NULL;
03778          *rc = who;
03779          if (option_debug)
03780             ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
03781          break;
03782       }
03783 
03784       other = (who == c0) ? c1 : c0; /* the 'other' channel */
03785       /* Try add the frame info the who's bridged channel jitterbuff */
03786       if (jb_in_use)
03787          frame_put_in_jb = !ast_jb_put(other, f);
03788 
03789       if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
03790          int bridge_exit = 0;
03791 
03792          switch (f->subclass) {
03793          case AST_CONTROL_HOLD:
03794          case AST_CONTROL_UNHOLD:
03795          case AST_CONTROL_VIDUPDATE:
03796          case AST_CONTROL_SRCUPDATE:
03797             ast_indicate_data(other, f->subclass, f->data, f->datalen);
03798             break;
03799          default:
03800             *fo = f;
03801             *rc = who;
03802             bridge_exit = 1;
03803             if (option_debug)
03804                ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
03805             break;
03806          }
03807          if (bridge_exit)
03808             break;
03809       }
03810       if ((f->frametype == AST_FRAME_VOICE) ||
03811           (f->frametype == AST_FRAME_DTMF_BEGIN) ||
03812           (f->frametype == AST_FRAME_DTMF) ||
03813           (f->frametype == AST_FRAME_VIDEO) ||
03814           (f->frametype == AST_FRAME_IMAGE) ||
03815           (f->frametype == AST_FRAME_HTML) ||
03816           (f->frametype == AST_FRAME_MODEM) ||
03817           (f->frametype == AST_FRAME_TEXT)) {
03818          /* monitored dtmf causes exit from bridge */
03819          int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
03820 
03821          if (monitored_source && 
03822             (f->frametype == AST_FRAME_DTMF_END || 
03823             f->frametype == AST_FRAME_DTMF_BEGIN)) {
03824             *fo = f;
03825             *rc = who;
03826             if (option_debug)
03827                ast_log(LOG_DEBUG, "Got DTMF %s on channel (%s)\n", 
03828                   f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
03829                   who->name);
03830             break;
03831          }
03832          /* Write immediately frames, not passed through jb */
03833          if (!frame_put_in_jb)
03834             ast_write(other, f);
03835             
03836          /* Check if we have to deliver now */
03837          if (jb_in_use)
03838             ast_jb_get_and_deliver(c0, c1);
03839       }
03840       /* XXX do we want to pass on also frames not matched above ? */
03841       ast_frfree(f);
03842 
03843       /* Swap who gets priority */
03844       cs[2] = cs[0];
03845       cs[0] = cs[1];
03846       cs[1] = cs[2];
03847    }
03848    return res;
03849 }

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

References channel_find_locked().

01125 {
01126    return channel_find_locked(NULL, NULL, 0, context, exten);
01127 }

struct ast_channel* ast_get_channel_by_name_locked ( const char *  name  ) 

Get channel by name (locks channel).

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

01106 {
01107    return channel_find_locked(NULL, name, 0, NULL, NULL);
01108 }

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

References channel_find_locked().

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

01112 {
01113    return channel_find_locked(NULL, name, namelen, NULL, NULL);
01114 }

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

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

Referenced by ast_device_state().

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

ast_group_t ast_get_group ( const char *  s  ) 

Definition at line 4293 of file channel.c.

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

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

04294 {
04295    char *piece;
04296    char *c;
04297    int start=0, finish=0, x;
04298    ast_group_t group = 0;
04299 
04300    if (ast_strlen_zero(s))
04301       return 0;
04302 
04303    c = ast_strdupa(s);
04304    
04305    while ((piece = strsep(&c, ","))) {
04306       if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
04307          /* Range */
04308       } else if (sscanf(piece, "%d", &start)) {
04309          /* Just one */
04310          finish = start;
04311       } else {
04312          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
04313          continue;
04314       }
04315       for (x = start; x <= finish; x++) {
04316          if ((x > 63) || (x < 0)) {
04317             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
04318          } else
04319             group |= ((ast_group_t) 1 << x);
04320       }
04321    }
04322    return group;
04323 }

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

References ast_audiohook_detach_list(), ast_autoservice_stop(), ast_cause2str(), ast_cdr_detach(), ast_cdr_end(), ast_channel_free(), ast_channel_lock, ast_channel_unlock, ast_closestream(), ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_set_flag, ast_test_flag, ast_channel::audiohooks, ast_channel::blocker, ast_channel::blockproc, ast_channel::cdr, CRASH, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, LOG_DEBUG, 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(), action_bridge(), agent_hangup(), agent_read(), alsa_new(), answer_exec_run(), 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(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_free(), conf_run(), connect_link(), do_hang(), do_parking_thread(), features_hangup(), findmeexec(), gtalk_new(), handle_enbloc_call_message(), handle_frame(), handle_frame_ownerless(), handle_hd_hf(), handle_init_event(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_soft_key_event_message(), handle_stimulus_message(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), local_attended_transfer(), local_hangup(), mgcp_new(), mgcp_ss(), monitor_dial(), nbs_new(), oss_new(), park_exec(), parkandannounce_exec(), phone_new(), rpt(), rpt_call(), rpt_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().

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

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

References ast_indicate_data().

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

02332 {
02333    return ast_indicate_data(chan, condition, NULL, 0);
02334 }

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 2336 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_SRCUPDATE, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FLAG_ZOMBIE, ast_get_indication_tone(), ast_log(), ast_playtones_start(), ast_playtones_stop(), ast_test_flag, tone_zone_sound::data, ast_channel_tech::indicate, LOG_DEBUG, option_debug, ast_channel::tech, ast_channel::visible_indication, and ast_channel::zone.

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

02337 {
02338    int res = -1;
02339 
02340    ast_channel_lock(chan);
02341    /* Stop if we're a zombie or need a soft hangup */
02342    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02343       ast_channel_unlock(chan);
02344       return -1;
02345    }
02346    if (chan->tech->indicate)
02347       res = chan->tech->indicate(chan, condition, data, datalen);
02348    ast_channel_unlock(chan);
02349    if (!chan->tech->indicate || res) {
02350       /*
02351        * Device does not support (that) indication, lets fake
02352        * it by doing our own tone generation. (PM2002)
02353        */
02354       if (condition < 0)
02355          ast_playtones_stop(chan);
02356       else {
02357          const struct tone_zone_sound *ts = NULL;
02358          switch (condition) {
02359          case AST_CONTROL_RINGING:
02360             ts = ast_get_indication_tone(chan->zone, "ring");
02361             break;
02362          case AST_CONTROL_BUSY:
02363             ts = ast_get_indication_tone(chan->zone, "busy");
02364             break;
02365          case AST_CONTROL_CONGESTION:
02366             ts = ast_get_indication_tone(chan->zone, "congestion");
02367             break;
02368          }
02369          if (ts && ts->data[0]) {
02370             if (option_debug)
02371                ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
02372             ast_playtones_start(chan,0,ts->data, 1);
02373             res = 0;
02374             chan->visible_indication = condition;
02375          } else if (condition == AST_CONTROL_PROGRESS) {
02376             /* ast_playtones_stop(chan); */
02377          } else if (condition == AST_CONTROL_PROCEEDING) {
02378             /* Do nothing, really */
02379          } else if (condition == AST_CONTROL_HOLD) {
02380             /* Do nothing.... */
02381          } else if (condition == AST_CONTROL_UNHOLD) {
02382             /* Do nothing.... */
02383          } else if (condition == AST_CONTROL_VIDUPDATE) {
02384             /* Do nothing.... */
02385          } else if (condition == AST_CONTROL_SRCUPDATE) {
02386             /* Do nothing... */
02387          } else {
02388             /* not handled */
02389             ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
02390             res = -1;
02391          }
02392       }
02393    } else
02394       chan->visible_indication = condition;
02395 
02396    return res;
02397 }

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

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by load_module(), and reload().

04332 {
04333    ast_moh_start_ptr = start_ptr;
04334    ast_moh_stop_ptr = stop_ptr;
04335    ast_moh_cleanup_ptr = cleanup_ptr;
04336 }

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

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

Referenced by add_sdp(), and ast_read_generator_actions().

02314 {
02315    int ret = ast_opt_internal_timing && chan->timingfd > -1;
02316    if (option_debug > 4)
02317       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);
02318    return ret;
02319 }

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

References ast_moh_cleanup_ptr.

Referenced by ast_channel_free().

04367 {
04368    if (ast_moh_cleanup_ptr)
04369       ast_moh_cleanup_ptr(chan);
04370 }

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

04347 {
04348    if (ast_moh_start_ptr)
04349       return ast_moh_start_ptr(chan, mclass, interpclass);
04350 
04351    if (option_verbose > 2) {
04352       ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n", 
04353          mclass ? mclass : (interpclass ? interpclass : "default"));
04354    }
04355 
04356    return 0;
04357 }

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

References ast_moh_stop_ptr.

Referenced by alsa_indicate(), app_exec(), ast_quiet_chan(), conf_run(), do_bridge_masquerade(), 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(), steal_channel(), try_calling(), and zt_indicate().

04361 {
04362    if (ast_moh_stop_ptr)
04363       ast_moh_stop_ptr(chan);
04364 }

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

print call- and pickup groups into buffer

Definition at line 4378 of file channel.c.

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

04379 {
04380    unsigned int i;
04381    int first=1;
04382    char num[3];
04383 
04384    buf[0] = '\0';
04385    
04386    if (!group) /* Return empty string if no group */
04387       return buf;
04388 
04389    for (i = 0; i <= 63; i++) {   /* Max group is 63 */
04390       if (group & ((ast_group_t) 1 << i)) {
04391             if (!first) {
04392             strncat(buf, ", ", buflen - strlen(buf) - 1);
04393          } else {
04394             first=0;
04395          }
04396          snprintf(num, sizeof(num), "%u", i);
04397          strncat(buf, num, buflen - strlen(buf) - 1);
04398       }
04399    }
04400    return buf;
04401 }

int ast_prod ( struct ast_channel chan  ) 

Send empty audio to prime a channel driver.

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

Referenced by ast_activate_generator().

02520 {
02521    struct ast_frame a = { AST_FRAME_VOICE };
02522    char nothing[128];
02523 
02524    /* Send an empty audio frame to get things moving */
02525    if (chan->_state != AST_STATE_UP) {
02526       if (option_debug)
02527          ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
02528       a.subclass = chan->rawwriteformat;
02529       a.data = nothing + AST_FRIENDLY_OFFSET;
02530       a.src = "ast_prod";
02531       if (ast_write(chan, &a))
02532          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
02533    }
02534    return 0;
02535 }

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(), 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 iax2_queue_control_data(), process_sdp(), skinny_hold(), 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, errno, f, ast_frame::frametype, LOG_DEBUG, option_debug, ast_frame::subclass, and ast_channel::timingfd.

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

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

02322 {
02323    return __ast_read(chan, 0);
02324 }

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

Definition at line 1884 of file channel.c.

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

Referenced by __ast_read().

01885 {
01886    if (chan->generatordata &&  !ast_internal_timing_enabled(chan)) {
01887       void *tmp = chan->generatordata;
01888       int res;
01889 
01890       if (chan->timingfunc) {
01891          if (option_debug > 1)
01892             ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
01893          ast_settimeout(chan, 0, NULL, NULL);
01894       }
01895 
01896       chan->generatordata = NULL;     /* reset, to let writes go through */
01897       res = chan->generator->generate(chan, tmp, f->datalen, f->samples);
01898       chan->generatordata = tmp;
01899       if (res) {
01900          if (option_debug > 1)
01901             ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01902          ast_deactivate_generator(chan);
01903       }
01904 
01905    } else if (f->frametype == AST_FRAME_CNG) {
01906       if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
01907          if (option_debug > 1)
01908             ast_log(LOG_DEBUG, "Generator got CNG, switching to timed mode\n");
01909          ast_settimeout(chan, 160, generator_force, chan);
01910       }
01911    }
01912 }

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

References __ast_read().

Referenced by conf_run().

02327 {
02328    return __ast_read(chan, 1);
02329 }

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

03050 {
03051    return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
03052 }

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

03055 {
03056    int pos = 0;   /* index in the buffer where we accumulate digits */
03057    int to = ftimeout;
03058 
03059    /* Stop if we're a zombie or need a soft hangup */
03060    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03061       return -1;
03062    if (!len)
03063       return -1;
03064    for (;;) {
03065       int d;
03066       if (c->stream) {
03067          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
03068          ast_stopstream(c);
03069          usleep(1000);
03070          if (!d)
03071             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03072       } else {
03073          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03074       }
03075       if (d < 0)
03076          return -1;
03077       if (d == 0) {
03078          s[pos]='\0';
03079          return 1;
03080       }
03081       if (d == 1) {
03082          s[pos]='\0';
03083          return 2;
03084       }
03085       if (!strchr(enders, d))
03086          s[pos++] = d;
03087       if (strchr(enders, d) || (pos >= len)) {
03088          s[pos]='\0';
03089          return 0;
03090       }
03091       to = timeout;
03092    }
03093    /* Never reached */
03094    return 0;
03095 }

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

References ast_recvtext(), and free.

Referenced by handle_recvchar().

02400 {
02401    int c;
02402    char *buf = ast_recvtext(chan, timeout);
02403    if (buf == NULL)
02404       return -1;  /* error or timeout */
02405    c = *(unsigned char *)buf;
02406    free(buf);
02407    return c;
02408 }

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

02411 {
02412    int res, done = 0;
02413    char *buf = NULL;
02414    
02415    while (!done) {
02416       struct ast_frame *f;
02417       if (ast_check_hangup(chan))
02418          break;
02419       res = ast_waitfor(chan, timeout);
02420       if (res <= 0) /* timeout or error */
02421          break;
02422       timeout = res; /* update timeout */
02423       f = ast_read(chan);
02424       if (f == NULL)
02425          break; /* no frame */
02426       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
02427          done = 1;   /* force a break */
02428       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
02429          buf = ast_strndup((char *) f->data, f->datalen);   /* dup and break */
02430          done = 1;
02431       }
02432       ast_frfree(f);
02433    }
02434    return buf;
02435 }

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

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, AST_FORMAT_AUDIO_MASK, AST_FORMAT_VIDEO_MASK, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), ast_translator_best_choice(), capabilities, ast_channel_tech::capabilities, channels, fmt, 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(), connect_link(), features_alloc(), findmeexec(), ring_entry(), rpt(), rpt_call(), rpt_tele_thread(), and wait_for_answer().

02958 {
02959    struct chanlist *chan;
02960    struct ast_channel *c;
02961    int capabilities;
02962    int fmt;
02963    int res;
02964    int foo;
02965    int videoformat = format & AST_FORMAT_VIDEO_MASK;
02966 
02967    if (!cause)
02968       cause = &foo;
02969    *cause = AST_CAUSE_NOTDEFINED;
02970 
02971    if (AST_LIST_LOCK(&channels)) {
02972       ast_log(LOG_WARNING, "Unable to lock channel list\n");
02973       return NULL;
02974    }
02975 
02976    AST_LIST_TRAVERSE(&backends, chan, list) {
02977       if (strcasecmp(type, chan->tech->type))
02978          continue;
02979 
02980       capabilities = chan->tech->capabilities;
02981       fmt = format & AST_FORMAT_AUDIO_MASK;
02982       res = ast_translator_best_choice(&fmt, &capabilities);
02983       if (res < 0) {
02984          ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
02985          *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
02986          AST_LIST_UNLOCK(&channels);
02987          return NULL;
02988       }
02989       AST_LIST_UNLOCK(&channels);
02990       if (!chan->tech->requester)
02991          return NULL;
02992       
02993       if (!(c = chan->tech->requester(type, capabilities | videoformat, data, cause)))
02994          return NULL;
02995 
02996       /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
02997       return c;
02998    }
02999 
03000    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
03001    *cause = AST_CAUSE_NOSUCHDRIVER;
03002    AST_LIST_UNLOCK(&channels);
03003 
03004    return NULL;
03005 }

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

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_exten().

02953 {
02954    return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
02955 }

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

References ast_safe_sleep_conditional().

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

01159 {
01160    return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
01161 }

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

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

Referenced by __login_exec(), and ast_safe_sleep().

01138 {
01139    struct ast_frame *f;
01140 
01141    while (ms > 0) {
01142       if (cond && ((*cond)(data) == 0))
01143          return 0;
01144       ms = ast_waitfor(chan, ms);
01145       if (ms < 0)
01146          return -1;
01147       if (ms > 0) {
01148          f = ast_read(chan);
01149          if (!f)
01150             return -1;
01151          ast_frfree(f);
01152       }
01153    }
01154    return 0;
01155 }

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

References ast_malloc, and len.

Referenced by features_new(), and zt_new().

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

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

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

04652 {
04653         return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
04654 }

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

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

04646 {
04647         return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
04648 }

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

Definition at line 4638 of file channel.c.

References ast_say_digits_full().

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

04640 {
04641         return ast_say_digits_full(chan, num, ints, lang, -1, -1);
04642 }

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

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

04664 {
04665         char buf[256];
04666 
04667         snprintf(buf, sizeof(buf), "%d", num);
04668         return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
04669 }

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

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

04634 {
04635         return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
04636 }

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

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

04628 {
04629         return ast_say_number_full(chan, num, ints, language, options, -1, -1);
04630 }

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

Definition at line 4656 of file channel.c.

References ast_say_phonetic_str_full.

Referenced by pbx_builtin_sayphonetic().

04658 {
04659         return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
04660 }

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

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

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

02510 {
02511    if (chan->tech->send_digit_begin) {
02512       ast_senddigit_begin(chan, digit);
02513       ast_safe_sleep(chan, AST_DEFAULT_EMULATE_DTMF_DURATION);
02514    }
02515    
02516    return ast_senddigit_end(chan, digit, AST_DEFAULT_EMULATE_DTMF_DURATION);
02517 }

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

02451 {
02452    /* Device does not support DTMF tones, lets fake
02453     * it by doing our own generation. */
02454    static const char* dtmf_tones[] = {
02455       "941+1336", /* 0 */
02456       "697+1209", /* 1 */
02457       "697+1336", /* 2 */
02458       "697+1477", /* 3 */
02459       "770+1209", /* 4 */
02460       "770+1336", /* 5 */
02461       "770+1477", /* 6 */
02462       "852+1209", /* 7 */
02463       "852+1336", /* 8 */
02464       "852+1477", /* 9 */
02465       "697+1633", /* A */
02466       "770+1633", /* B */
02467       "852+1633", /* C */
02468       "941+1633", /* D */
02469       "941+1209", /* * */
02470       "941+1477"  /* # */
02471    };
02472 
02473    if (!chan->tech->send_digit_begin)
02474       return 0;
02475 
02476    if (!chan->tech->send_digit_begin(chan, digit))
02477       return 0;
02478 
02479    if (digit >= '0' && digit <='9')
02480       ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
02481    else if (digit >= 'A' && digit <= 'D')
02482       ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
02483    else if (digit == '*')
02484       ast_playtones_start(chan, 0, dtmf_tones[14], 0);
02485    else if (digit == '#')
02486       ast_playtones_start(chan, 0, dtmf_tones[15], 0);
02487    else {
02488       /* not handled */
02489       if (option_debug)
02490          ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
02491    }
02492 
02493    return 0;
02494 }

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

02497 {
02498    int res = -1;
02499 
02500    if (chan->tech->send_digit_end)
02501       res = chan->tech->send_digit_end(chan, digit, duration);
02502 
02503    if (res && chan->generator)
02504       ast_playtones_stop(chan);
02505    
02506    return 0;
02507 }

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

02438 {
02439    int res = 0;
02440    /* Stop if we're a zombie or need a soft hangup */
02441    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02442       return -1;
02443    CHECK_BLOCKING(chan);
02444    if (chan->tech->send_text)
02445       res = chan->tech->send_text(chan, text);
02446    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02447    return res;
02448 }

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

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

Definition at line 3598 of file channel.c.

References ast_cdr_setcid(), ast_channel_lock, ast_channel_unlock, ast_describe_caller_presentation(), ast_strdup, ast_channel::cdr, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, 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(), setcallerid_exec(), skinny_newcall(), ss_thread(), wait_for_answer(), and zt_read().

03599 {
03600    ast_channel_lock(chan);
03601 
03602    if (callerid) {
03603       if (chan->cid.cid_num)
03604          free(chan->cid.cid_num);
03605       chan->cid.cid_num = ast_strdup(callerid);
03606    }
03607    if (calleridname) {
03608       if (chan->cid.cid_name)
03609          free(chan->cid.cid_name);
03610       chan->cid.cid_name = ast_strdup(calleridname);
03611    }
03612    if (ani) {
03613       if (chan->cid.cid_ani)
03614          free(chan->cid.cid_ani);
03615       chan->cid.cid_ani = ast_strdup(ani);
03616    }
03617    if (chan->cdr)
03618       ast_cdr_setcid(chan->cdr, chan);
03619    manager_event(EVENT_FLAG_CALL, "Newcallerid",
03620             "Channel: %s\r\n"
03621             "CallerID: %s\r\n"
03622             "CallerIDName: %s\r\n"
03623             "Uniqueid: %s\r\n"
03624             "CID-CallingPres: %d (%s)\r\n",
03625             chan->name,
03626             S_OR(chan->cid.cid_num, "<Unknown>"),
03627             S_OR(chan->cid.cid_name, "<Unknown>"),
03628             chan->uniqueid,
03629             chan->cid.cid_pres,
03630             ast_describe_caller_presentation(chan->cid.cid_pres)
03631             );
03632    
03633    ast_channel_unlock(chan);
03634 }

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 2788 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_do_masquerade(), ast_set_best_format(), attempt_reconnect(), background_detect_exec(), build_conf(), conf_run(), connect_link(), dictate_exec(), disa_exec(), do_waiting(), eagi_exec(), echo_exec(), gtalk_rtp_read(), handle_recordfile(), ices_exec(), isAnsweringMachine(), measurenoise(), mgcp_rtp_read(), milliwatt_exec(), mwanalyze_exec(), nv_background_detect_exec(), nv_detectfax_exec(), oh323_rtp_read(), process_sdp(), rpt(), rxfax_exec(), setup_rtp_connection(), sip_rtp_read(), skinny_rtp_read(), socket_process(), speech_background(), txfax_exec(), and update_features().

02789 {
02790    return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
02791            &chan->readtrans, 0);
02792 }

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

04404 {
04405    struct ast_variable *cur;
04406 
04407    for (cur = vars; cur; cur = cur->next)
04408       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
04409 }

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 2794 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_do_masquerade(), ast_openstream_full(), ast_set_best_format(), ast_stopstream(), attempt_reconnect(), build_conf(), chanspy_exec(), conf_run(), connect_link(), disa_exec(), echo_exec(), extenspy_exec(), gtalk_rtp_read(), linear_alloc(), linear_release(), mgcp_rtp_read(), 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(), 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().

02795 {
02796    return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
02797            &chan->writetrans, 1);
02798 }

int ast_setstate ( struct ast_channel chan,
enum ast_channel_state  state 
)

Change the state of a channel.

Definition at line 3636 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, manager_event(), and S_OR.

Referenced by __ast_read(), __oh323_update_info(), __zt_exception(), agent_call(), alsa_answer(), ast_answer(), cb_events(), check_availability(), do_bridge_masquerade(), 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().

03637 {
03638    int oldstate = chan->_state;
03639 
03640    if (oldstate == state)
03641       return 0;
03642 
03643    chan->_state = state;
03644    ast_device_state_changed_literal(chan->name);
03645    /* setstate used to conditionally report Newchannel; this is no more */
03646    manager_event(EVENT_FLAG_CALL,
03647             "Newstate",
03648             "Channel: %s\r\n"
03649             "State: %s\r\n"
03650             "CallerID: %s\r\n"
03651             "CallerIDName: %s\r\n"
03652             "Uniqueid: %s\r\n",
03653             chan->name, ast_state2str(chan->_state),
03654             S_OR(chan->cid.cid_num, "<unknown>"),
03655             S_OR(chan->cid.cid_name, "<unknown>"),
03656             chan->uniqueid);
03657 
03658    return 0;
03659 }

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

Definition at line 1792 of file channel.c.

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

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

01793 {
01794    int res = -1;
01795 #ifdef HAVE_ZAPTEL
01796    if (c->timingfd > -1) {
01797       if (!func) {
01798          samples = 0;
01799          data = 0;
01800       }
01801       if (option_debug)
01802          ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01803       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01804       c->timingfunc = func;
01805       c->timingdata = data;
01806    }
01807 #endif   
01808    return res;
01809 }

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

Referenced by handle_request_options().

00461 {
00462    return shutting_down;
00463 }

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

References ast_channel_lock, ast_channel_unlock, and ast_softhangup_nolock().

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

01394 {
01395    int res;
01396    ast_channel_lock(chan);
01397    res = ast_softhangup_nolock(chan, cause);
01398    ast_channel_unlock(chan);
01399    return res;
01400 }

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

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

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

01380 {
01381    if (option_debug)
01382       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
01383    /* Inform channel driver that we need to be hung up, if it cares */
01384    chan->_softhangup |= cause;
01385    ast_queue_frame(chan, &ast_null_frame);
01386    /* Interrupt any poll call or such */
01387    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
01388       pthread_kill(chan->blocker, SIGURG);
01389    return 0;
01390 }

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

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

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

References causes.

Referenced by pbx_builtin_hangup().

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

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

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

Referenced by zapateller_exec().

04276 {
04277    int res;
04278 
04279    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
04280       return res;
04281 
04282    /* Give us some wiggle room */
04283    while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
04284       struct ast_frame *f = ast_read(chan);
04285       if (f)
04286          ast_frfree(f);
04287       else
04288          return -1;
04289    }
04290    return 0;
04291 }

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

Start a tone going

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

04258 {
04259    struct tonepair_def d = { 0, };
04260 
04261    d.freq1 = freq1;
04262    d.freq2 = freq2;
04263    d.duration = duration;
04264    d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */
04265    if (ast_activate_generator(chan, &tonepair, &d))
04266       return -1;
04267    return 0;
04268 }

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 4270 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

04271 {
04272    ast_deactivate_generator(chan);
04273 }

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

03032 {
03033    int res = -1;
03034 
03035    /* Stop if we're a zombie or need a soft hangup */
03036    ast_channel_lock(chan);
03037    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03038       if (chan->tech->transfer) {
03039          res = chan->tech->transfer(chan, dest);
03040          if (!res)
03041             res = 1;
03042       } else
03043          res = 0;
03044    }
03045    ast_channel_unlock(chan);
03046    return res;
03047 }

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

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

void ast_uninstall_music_functions ( void   ) 

Definition at line 4338 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

04339 {
04340    ast_moh_start_ptr = NULL;
04341    ast_moh_stop_ptr = NULL;
04342    ast_moh_cleanup_ptr = NULL;
04343 }

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

01777 {
01778    int oldms = ms;   /* -1 if no timeout */
01779 
01780    ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
01781    if ((ms < 0) && (oldms < 0))
01782       ms = 0;
01783    return ms;
01784 }

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

References ast_waitfor_nandfds().

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

01772 {
01773    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
01774 }

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

References ast_waitfor_nandfds().

Referenced by dundi_lookup_internal(), and dundi_precache_internal().

01616 {
01617    int winner = -1;
01618    ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
01619    return winner;
01620 }

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

References ast_channel::_softhangup, ast_add_fd(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, ast_log(), AST_MAX_FDS, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, CHECK_BLOCKING, errno, pollfd::fd, 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().

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

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

References ast_waitfordigit_full().

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

01788 {
01789    return ast_waitfordigit_full(c, ms, -1, -1);
01790 }

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

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

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

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

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

References channel_find_locked().

Referenced by next_channel().

01132 {
01133    return channel_find_locked(chan, NULL, 0, context, exten);
01134 }

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

References channel_find_locked().

Referenced by next_channel().

01119 {
01120    return channel_find_locked(chan, name, namelen, NULL, NULL);
01121 }

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

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

Referenced by adsi_careful_send(), agent_write(), ast_prod(), ast_readaudio_callback(), ast_readvideo_callback(), ast_udptl_bridge(), ast_write_video(), bridge_native_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(), 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().

02549 {
02550    int res = -1;
02551    int count = 0;
02552    struct ast_frame *f = NULL, *f2 = NULL;
02553 
02554    /*Deadlock avoidance*/
02555    while(ast_channel_trylock(chan)) {
02556       /*cannot goto done since the channel is not locked*/
02557       if(count++ > 10) {
02558          if(option_debug)
02559             ast_log(LOG_DEBUG, "Deadlock avoided for write to channel '%s'\n", chan->name);
02560          return 0;
02561       }
02562       usleep(1);
02563    }
02564    /* Stop if we're a zombie or need a soft hangup */
02565    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02566       goto done;
02567 
02568    /* Handle any pending masquerades */
02569    if (chan->masq && ast_do_masquerade(chan)) {
02570       ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02571       goto done;
02572    }
02573    if (chan->masqr) {
02574       res = 0; /* XXX explain, why 0 ? */
02575       goto done;
02576    }
02577    if (chan->generatordata) {
02578       if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
02579          ast_deactivate_generator(chan);
02580       else {
02581          if (fr->frametype == AST_FRAME_DTMF_END) {
02582             /* There is a generator running while we're in the middle of a digit.
02583              * It's probably inband DTMF, so go ahead and pass it so it can
02584              * stop the generator */
02585             ast_clear_flag(chan, AST_FLAG_BLOCKING);
02586             ast_channel_unlock(chan);
02587             res = ast_senddigit_end(chan, fr->subclass, fr->len);
02588             ast_channel_lock(chan);
02589             CHECK_BLOCKING(chan);
02590          } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass == AST_CONTROL_UNHOLD) {
02591             /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */
02592             res = (chan->tech->indicate == NULL) ? 0 :
02593                chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
02594          }
02595          res = 0; /* XXX explain, why 0 ? */
02596          goto done;
02597       }
02598    }
02599    /* High bit prints debugging */
02600    if (chan->fout & DEBUGCHAN_FLAG)
02601       ast_frame_dump(chan->name, fr, ">>");
02602    CHECK_BLOCKING(chan);
02603    switch(fr->frametype) {
02604    case AST_FRAME_CONTROL:
02605       res = (chan->tech->indicate == NULL) ? 0 :
02606          chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
02607       break;
02608    case AST_FRAME_DTMF_BEGIN:
02609       if (chan->audiohooks) {
02610          struct ast_frame *old_frame = fr;
02611          fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02612          if (old_frame != fr)
02613             f = fr;
02614       }
02615       ast_clear_flag(chan, AST_FLAG_BLOCKING);
02616       ast_channel_unlock(chan);
02617       res = ast_senddigit_begin(chan, fr->subclass);
02618       ast_channel_lock(chan);
02619       CHECK_BLOCKING(chan);
02620       break;
02621    case AST_FRAME_DTMF_END:
02622       if (chan->audiohooks) {
02623          struct ast_frame *old_frame = fr;
02624          fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02625          if (old_frame != fr)
02626             f = fr;
02627       }
02628       ast_clear_flag(chan, AST_FLAG_BLOCKING);
02629       ast_channel_unlock(chan);
02630       res = ast_senddigit_end(chan, fr->subclass, fr->len);
02631       ast_channel_lock(chan);
02632       CHECK_BLOCKING(chan);
02633       break;
02634    case AST_FRAME_TEXT:
02635       res = (chan->tech->send_text == NULL) ? 0 :
02636          chan->tech->send_text(chan, (char *) fr->data);
02637       break;
02638    case AST_FRAME_HTML:
02639       res = (chan->tech->send_html == NULL) ? 0 :
02640          chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
02641       break;
02642    case AST_FRAME_VIDEO:
02643       /* XXX Handle translation of video codecs one day XXX */
02644       res = (chan->tech->write_video == NULL) ? 0 :
02645          chan->tech->write_video(chan, fr);
02646       break;
02647    case AST_FRAME_MODEM:
02648       res = (chan->tech->write == NULL) ? 0 :
02649          chan->tech->write(chan, fr);
02650       break;
02651    case AST_FRAME_VOICE:
02652       if (chan->tech->write == NULL)
02653          break;   /*! \todo XXX should return 0 maybe ? */
02654 
02655       if (chan->audiohooks) {
02656          struct ast_frame *old_frame = fr;
02657          fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02658          if (old_frame != fr)
02659             f2 = fr;
02660       }
02661       
02662       /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
02663       if (fr->subclass == chan->rawwriteformat)
02664          f = fr;
02665       else
02666          f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
02667 
02668       /* If we have no frame of audio, then we have to bail out */
02669       if (!f) {
02670          res = 0;
02671          break;
02672       }
02673 
02674       /* If Monitor is running on this channel, then we have to write frames out there too */
02675       if (chan->monitor && chan->monitor->write_stream) {
02676          /* XXX must explain this code */
02677 #ifndef MONITOR_CONSTANT_DELAY
02678          int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
02679          if (jump >= 0) {
02680             jump = chan->insmpl - chan->outsmpl;
02681             if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
02682                ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02683             chan->outsmpl += jump + f->samples;
02684          } else
02685             chan->outsmpl += f->samples;
02686 #else
02687          int jump = chan->insmpl - chan->outsmpl;
02688          if (jump - MONITOR_DELAY >= 0) {
02689             if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02690                ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02691             chan->outsmpl += jump;
02692          } else
02693             chan->outsmpl += f->samples;
02694 #endif
02695          if (chan->monitor->state == AST_MONITOR_RUNNING) {
02696             if (ast_writestream(chan->monitor->write_stream, f) < 0)
02697                ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
02698          }
02699       }
02700 
02701       if (f) 
02702          res = chan->tech->write(chan,f);
02703       else
02704          res = 0;
02705       break;
02706    case AST_FRAME_NULL:
02707    case AST_FRAME_IAX:
02708       /* Ignore these */
02709       res = 0;
02710       break;
02711    default:
02712       /* At this point, fr is the incoming frame and f is NULL.  Channels do
02713        * not expect to get NULL as a frame pointer and will segfault.  Hence,
02714        * we output the original frame passed in. */
02715       res = chan->tech->write(chan, fr);
02716       break;
02717    }
02718 
02719    if (f && f != fr)
02720       ast_frfree(f);
02721    if (f2)
02722       ast_frfree(f2);
02723    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02724    /* Consider a write failure to force a soft hangup */
02725    if (res < 0)
02726       chan->_softhangup |= AST_SOFTHANGUP_DEV;
02727    else {
02728       chan->fout = FRAMECOUNT_INC(chan->fout);
02729    }
02730 done:
02731    ast_channel_unlock(chan);
02732    return res;
02733 }

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

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

02538 {
02539    int res;
02540    if (!chan->tech->write_video)
02541       return 0;
02542    res = ast_write(chan, fr);
02543    if (!res)
02544       res = 1;
02545    return res;
02546 }

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

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

03672 {
03673    int min = 0, sec = 0, check;
03674 
03675    check = ast_autoservice_start(peer);
03676    if (check)
03677       return;
03678 
03679    if (remain > 0) {
03680       if (remain / 60 > 1) {
03681          min = remain / 60;
03682          sec = remain % 60;
03683       } else {
03684          sec = remain;
03685       }
03686    }
03687    
03688    if (!strcmp(sound,"timeleft")) { /* Queue support */
03689       ast_stream_and_wait(chan, "vm-youhave", chan->language, "");
03690       if (min) {
03691          ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
03692          ast_stream_and_wait(chan, "queue-minutes", chan->language, "");
03693       }
03694       if (sec) {
03695          ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
03696          ast_stream_and_wait(chan, "queue-seconds", chan->language, "");
03697       }
03698    } else {
03699       ast_stream_and_wait(chan, sound, chan->language, "");
03700    }
03701 
03702    ast_autoservice_stop(peer);
03703 }

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(), channels, ast_channel::context, ast_channel::exten, LOG_DEBUG, ast_channel::macrocontext, ast_channel::macroexten, and option_debug.

Referenced by ast_channel_walk_locked(), ast_get_channel_by_exten_locked(), ast_get_channel_by_name_locked(), ast_get_channel_by_name_prefix_locked(), ast_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    const struct ast_channel *_prev = prev;
01024 
01025    for (retries = 0; retries < 10; retries++) {
01026       int done;
01027       AST_LIST_LOCK(&channels);
01028       AST_LIST_TRAVERSE(&channels, c, chan_list) {
01029          prev = _prev;
01030          if (prev) { /* look for next item */
01031             if (c != prev) /* not this one */
01032                continue;
01033             /* found, prepare to return c->next */
01034             if ((c = AST_LIST_NEXT(c, chan_list)) == NULL) break;
01035             /* If prev was the last item on the channel list, then we just
01036              * want to return NULL, instead of trying to deref NULL in the
01037              * next section.
01038              */
01039             prev = NULL;
01040             /* We want prev to be NULL in case we end up doing more searching through
01041              * the channel list to find the channel (ie: name searching). If we didn't
01042              * set this to NULL the logic would just blow up
01043              * XXX Need a better explanation for this ...
01044              */
01045          }
01046          if (name) { /* want match by name */
01047             if ((!namelen && strcasecmp(c->name, name)) ||
01048                 (namelen && strncasecmp(c->name, name, namelen)))
01049                continue;   /* name match failed */
01050          } else if (exten) {
01051             if (context && strcasecmp(c->context, context) &&
01052                 strcasecmp(c->macrocontext, context))
01053                continue;   /* context match failed */
01054             if (strcasecmp(c->exten, exten) &&
01055                 strcasecmp(c->macroexten, exten))
01056                continue;   /* exten match failed */
01057          }
01058          /* if we get here, c points to the desired record */
01059          break;
01060       }
01061       /* exit if chan not found or mutex acquired successfully */
01062       /* this is slightly unsafe, as we _should_ hold the lock to access c->name */
01063       done = c == NULL || ast_channel_trylock(c) == 0;
01064       if (!done) {
01065          if (option_debug)
01066             ast_log(LOG_DEBUG, "Avoiding %s for channel '%p'\n", msg, c);
01067          if (retries == 9) {
01068             /* We are about to fail due to a deadlock, so report this
01069              * while we still have the list lock.
01070              */
01071             if (option_debug)
01072                ast_log(LOG_DEBUG, "Failure, could not lock '%p' after %d retries!\n", c, retries);
01073             /* As we have deadlocked, we will skip this channel and
01074              * see if there is another match.
01075              * NOTE: No point doing this for a full-name match,
01076              * as there can be no more matches.
01077              */
01078             if (!(name && !namelen)) {
01079                prev = c;
01080                retries = -1;
01081             }
01082          }
01083       }
01084       AST_LIST_UNLOCK(&channels);
01085       if (done)
01086          return c;
01087       /* If we reach this point we basically tried to lock a channel and failed. Instead of
01088        * starting from the beginning of the list we can restore our saved pointer to the previous
01089        * channel and start from there.
01090        */
01091       prev = _prev;
01092       usleep(1);  /* give other threads a chance before retrying */
01093    }
01094 
01095    return NULL;
01096 }

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

References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.

04491 {
04492    switch (reason) {
04493    case CHANNEL_MODULE_LOAD:
04494       return "LOAD (Channel module load)";
04495 
04496    case CHANNEL_MODULE_RELOAD:
04497       return "RELOAD (Channel module reload)";
04498 
04499    case CHANNEL_CLI_RELOAD:
04500       return "CLIRELOAD (Channel module reload by CLI command)";
04501 
04502    default:
04503       return "MANAGERRELOAD (Channel module reload by manager)";
04504    }
04505 };

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

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

Referenced by ast_do_masquerade().

03314 {
03315    struct ast_var_t *current, *newvar;
03316    /* Append variables from clone channel into original channel */
03317    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
03318    if (AST_LIST_FIRST(&clone->varshead))
03319       AST_LIST_APPEND_LIST(&original->varshead, &clone->varshead, entries);
03320 
03321    /* then, dup the varshead list into the clone */
03322    
03323    AST_LIST_TRAVERSE(&original->varshead, current, entries) {
03324       newvar = ast_var_assign(current->name, current->value);
03325       if (newvar)
03326          AST_LIST_INSERT_TAIL(&clone->varshead, newvar, entries);
03327    }
03328 }

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

Definition at line 333 of file channel.c.

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

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

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

Definition at line 311 of file channel.c.

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

00312 {
00313    struct chanlist *cl;
00314    int which = 0;
00315    int wordlen;
00316    char *ret = NULL;
00317 
00318    if (pos != 2)
00319       return NULL;
00320 
00321    wordlen = strlen(word);
00322 
00323    AST_LIST_TRAVERSE(&backends, cl, list) {
00324       if (!strncasecmp(word, cl->tech->type, wordlen) && ++which > state) {
00325          ret = strdup(cl->tech->type);
00326          break;
00327       }
00328    }
00329    
00330    return ret;
00331 }

static void free_cid ( struct ast_callerid cid  )  [static]

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

01164 {
01165    if (cid->cid_dnid)
01166       free(cid->cid_dnid);
01167    if (cid->cid_num)
01168       free(cid->cid_num);  
01169    if (cid->cid_name)
01170       free(cid->cid_name); 
01171    if (cid->cid_ani)
01172       free(cid->cid_ani);
01173    if (cid->cid_rdnis)
01174       free(cid->cid_rdnis);
01175 }

static void free_translation ( struct ast_channel clone  )  [static]

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

01403 {
01404    if (clone->writetrans)
01405       ast_translator_free_path(clone->writetrans);
01406    if (clone->readtrans)
01407       ast_translator_free_path(clone->readtrans);
01408    clone->writetrans = NULL;
01409    clone->readtrans = NULL;
01410    clone->rawwriteformat = clone->nativeformats;
01411    clone->rawreadformat = clone->nativeformats;
01412 }

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

Definition at line 1556 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_deactivate_generator(), ast_log(), LOG_DEBUG, and option_debug.

Referenced by ast_activate_generator(), and ast_read_generator_actions().

01557 {
01558    /* Called if generator doesn't have data */
01559    void *tmp;
01560    int res;
01561    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
01562    struct ast_channel *chan = (struct ast_channel *)data;
01563 
01564    ast_channel_lock(chan);
01565    tmp = chan->generatordata;
01566    chan->generatordata = NULL;
01567    if (chan->generator)
01568       generate = chan->generator->generate;
01569    ast_channel_unlock(chan);
01570 
01571    if (!tmp || !generate)
01572       return 0;
01573 
01574    res = generate(chan, tmp, 0, 160);
01575 
01576    chan->generatordata = tmp;
01577 
01578    if (res) {
01579       if (option_debug)
01580          ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01581       ast_deactivate_generator(chan);
01582    }
01583 
01584    return 0;
01585 }

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

Referenced by ast_set_read_format(), and ast_set_write_format().

02737 {
02738    int native;
02739    int res;
02740    
02741    /* Make sure we only consider audio */
02742    fmt &= AST_FORMAT_AUDIO_MASK;
02743    
02744    native = chan->nativeformats;
02745    /* Find a translation path from the native format to one of the desired formats */
02746    if (!direction)
02747       /* reading */
02748       res = ast_translator_best_choice(&fmt, &native);
02749    else
02750       /* writing */
02751       res = ast_translator_best_choice(&native, &fmt);
02752 
02753    if (res < 0) {
02754       ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
02755          ast_getformatname(native), ast_getformatname(fmt));
02756       return -1;
02757    }
02758    
02759    /* Now we have a good choice for both. */
02760    ast_channel_lock(chan);
02761 
02762    if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
02763       /* the channel is already in these formats, so nothing to do */
02764       ast_channel_unlock(chan);
02765       return 0;
02766    }
02767 
02768    *rawformat = native;
02769    /* User perspective is fmt */
02770    *format = fmt;
02771    /* Free any read translation we have right now */
02772    if (*trans)
02773       ast_translator_free_path(*trans);
02774    /* Build a translation path from the raw format to the desired format */
02775    if (!direction)
02776       /* reading */
02777       *trans = ast_translator_build_path(*format, *rawformat);
02778    else
02779       /* writing */
02780       *trans = ast_translator_build_path(*rawformat, *format);
02781    ast_channel_unlock(chan);
02782    if (option_debug)
02783       ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name,
02784          direction ? "write" : "read", ast_getformatname(fmt));
02785    return 0;
02786 }

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

Definition at line 258 of file channel.c.

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

00259 {
00260    struct chanlist *cl = NULL;
00261 
00262    if (argc != 4)
00263       return RESULT_SHOWUSAGE;
00264    
00265    if (AST_LIST_LOCK(&channels)) {
00266       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00267       return RESULT_FAILURE;
00268    }
00269 
00270    AST_LIST_TRAVERSE(&backends, cl, list) {
00271       if (!strncasecmp(cl->tech->type, argv[3], strlen(cl->tech->type))) {
00272          break;
00273       }
00274    }
00275 
00276 
00277    if (!cl) {
00278       ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[3]);
00279       AST_LIST_UNLOCK(&channels);
00280       return RESULT_FAILURE;
00281    }
00282 
00283    ast_cli(fd,
00284       "-- Info about channel driver: %s --\n"
00285       "  Device State: %s\n"
00286       "    Indication: %s\n"
00287       "     Transfer : %s\n"
00288       "  Capabilities: %d\n"
00289       "   Digit Begin: %s\n"
00290       "     Digit End: %s\n"
00291       "    Send HTML : %s\n"
00292       " Image Support: %s\n"
00293       "  Text Support: %s\n",
00294       cl->tech->type,
00295       (cl->tech->devicestate) ? "yes" : "no",
00296       (cl->tech->indicate) ? "yes" : "no",
00297       (cl->tech->transfer) ? "yes" : "no",
00298       (cl->tech->capabilities) ? cl->tech->capabilities : -1,
00299       (cl->tech->send_digit_begin) ? "yes" : "no",
00300       (cl->tech->send_digit_end) ? "yes" : "no",
00301       (cl->tech->send_html) ? "yes" : "no",
00302       (cl->tech->send_image) ? "yes" : "no",
00303       (cl->tech->send_text) ? "yes" : "no"
00304       
00305    );
00306 
00307    AST_LIST_UNLOCK(&channels);
00308    return RESULT_SUCCESS;
00309 }

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

Definition at line 205 of file channel.c.

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

00206 {
00207    struct chanlist *cl = NULL;
00208 
00209    if (argc != 3)
00210       return RESULT_SHOWUSAGE;
00211    
00212    if (AST_LIST_LOCK(&channels)) {
00213       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00214       return RESULT_FAILURE;
00215    }
00216 
00217    AST_LIST_TRAVERSE(&backends, cl, list) {
00218       if (!strncasecmp(cl->tech->type, argv[2], strlen(cl->tech->type))) {
00219          break;
00220       }
00221    }
00222 
00223 
00224    if (!cl) {
00225       ast_cli(fd, "\n%s is not a registered channel driver.\n", argv[2]);
00226       AST_LIST_UNLOCK(&channels);
00227       return RESULT_FAILURE;
00228    }
00229 
00230    ast_cli(fd,
00231       "-- Info about channel driver: %s --\n"
00232       "  Device State: %s\n"
00233       "    Indication: %s\n"
00234       "     Transfer : %s\n"
00235       "  Capabilities: %d\n"
00236       "   Digit Begin: %s\n"
00237       "     Digit End: %s\n"
00238       "    Send HTML : %s\n"
00239       " Image Support: %s\n"
00240       "  Text Support: %s\n",
00241       cl->tech->type,
00242       (cl->tech->devicestate) ? "yes" : "no",
00243       (cl->tech->indicate) ? "yes" : "no",
00244       (cl->tech->transfer) ? "yes" : "no",
00245       (cl->tech->capabilities) ? cl->tech->capabilities : -1,
00246       (cl->tech->send_digit_begin) ? "yes" : "no",
00247       (cl->tech->send_digit_end) ? "yes" : "no",
00248       (cl->tech->send_html) ? "yes" : "no",
00249       (cl->tech->send_image) ? "yes" : "no",
00250       (cl->tech->send_text) ? "yes" : "no"
00251       
00252    );
00253 
00254    AST_LIST_UNLOCK(&channels);
00255    return RESULT_SUCCESS;
00256 }

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

Definition at line 178 of file channel.c.

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

00179 {
00180 #define FORMAT  "%-10.10s  %-40.40s %-12.12s %-12.12s %-12.12s\n"
00181    struct chanlist *cl;
00182    int count_chan = 0;
00183 
00184    ast_cli(fd, FORMAT, "Type", "Description",       "Devicestate", "Indications", "Transfer");
00185    ast_cli(fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
00186    if (AST_LIST_LOCK(&channels)) {
00187       ast_log(LOG_WARNING, "Unable to lock channel list\n");
00188       return -1;
00189    }
00190    AST_LIST_TRAVERSE(&backends, cl, list) {
00191       ast_cli(fd, FORMAT, cl->tech->type, cl->tech->description,
00192          (cl->tech->devicestate) ? "yes" : "no",
00193          (cl->tech->indicate) ? "yes" : "no",
00194          (cl->tech->transfer) ? "yes" : "no");
00195       count_chan++;
00196    }
00197    AST_LIST_UNLOCK(&channels);
00198    ast_cli(fd, "----------\n%d channel drivers registered.\n", count_chan);
00199    return RESULT_SUCCESS;
00200 
00201 #undef FORMAT
00202 
00203 }

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

Definition at line 4411 of file channel.c.

04412 {
04413    /* just store the data pointer in the channel structure */
04414    return data;
04415 }

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

Definition at line 4422 of file channel.c.

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

04423 {
04424    short buf[samples];
04425    struct ast_frame frame = {
04426       .frametype = AST_FRAME_VOICE,
04427       .subclass = AST_FORMAT_SLINEAR,
04428       .data = buf,
04429       .samples = samples,
04430       .datalen = sizeof(buf),
04431    };
04432    memset(buf, 0, sizeof(buf));
04433    if (ast_write(chan, &frame))
04434       return -1;
04435    return 0;
04436 }

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

Definition at line 4417 of file channel.c.

04418 {
04419    /* nothing to do */
04420 }

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

Definition at line 4175 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, tonepair_release(), tonepair_def::vol, and ast_channel::writeformat.

04176 {
04177    struct tonepair_state *ts;
04178    struct tonepair_def *td = params;
04179 
04180    if (!(ts = ast_calloc(1, sizeof(*ts))))
04181       return NULL;
04182    ts->origwfmt = chan->writeformat;
04183    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
04184       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
04185       tonepair_release(NULL, ts);
04186       ts = NULL;
04187    } else {
04188       ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
04189       ts->v1_1 = 0;
04190       ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
04191       ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
04192       ts->v2_1 = 0;
04193       ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
04194       ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
04195       ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
04196       ts->duration = td->duration;
04197       ts->modulate = 0;
04198    }
04199    /* Let interrupts interrupt :) */
04200    ast_set_flag(chan, AST_FLAG_WRITE_INT);
04201    return ts;
04202 }

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

Definition at line 4204 of file channel.c.

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

04205 {
04206    struct tonepair_state *ts = data;
04207    int x;
04208 
04209    /* we need to prepare a frame with 16 * timelen samples as we're
04210     * generating SLIN audio
04211     */
04212    len = samples * 2;
04213 
04214    if (len > sizeof(ts->data) / 2 - 1) {
04215       ast_log(LOG_WARNING, "Can't generate that much data!\n");
04216       return -1;
04217    }
04218    memset(&ts->f, 0, sizeof(ts->f));
04219    for (x=0;x<len/2;x++) {
04220       ts->v1_1 = ts->v2_1;
04221       ts->v2_1 = ts->v3_1;
04222       ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
04223       
04224       ts->v1_2 = ts->v2_2;
04225       ts->v2_2 = ts->v3_2;
04226       ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
04227       if (ts->modulate) {
04228          int p;
04229          p = ts->v3_2 - 32768;
04230          if (p < 0) p = -p;
04231          p = ((p * 9) / 10) + 1;
04232          ts->data[x] = (ts->v3_1 * p) >> 15;
04233       } else
04234          ts->data[x] = ts->v3_1 + ts->v3_2; 
04235    }
04236    ts->f.frametype = AST_FRAME_VOICE;
04237    ts->f.subclass = AST_FORMAT_SLINEAR;
04238    ts->f.datalen = len;
04239    ts->f.samples = samples;
04240    ts->f.offset = AST_FRIENDLY_OFFSET;
04241    ts->f.data = ts->data;
04242    ast_write(chan, &ts->f);
04243    ts->pos += x;
04244    if (ts->duration > 0) {
04245       if (ts->pos >= ts->duration * 8)
04246          return -1;
04247    }
04248    return 0;
04249 }

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

Definition at line 4166 of file channel.c.

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

Referenced by tonepair_alloc().

04167 {
04168    struct tonepair_state *ts = params;
04169 
04170    if (chan)
04171       ast_set_write_format(chan, ts->origwfmt);
04172    free(ts);
04173 }


Variable Documentation

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

Definition at line 4327 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 4325 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 4326 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 373 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 368 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 363 of file channel.c.

unsigned long global_fin

Definition at line 82 of file channel.c.

unsigned long global_fout

Definition at line 82 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 702 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 359 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 355 of file channel.c.

int shutting_down [static]

Prevent new channel allocation if shutting down.

Definition at line 78 of file channel.c.

struct ast_generator silence_generator [static]

Initial value:

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

Referenced by ast_tonepair_start().

int uniqueint [static]

Definition at line 80 of file channel.c.


Generated on Mon Mar 31 07:39:48 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1