Mon Jul 14 17:25:15 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 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)
ast_channel__ast_request_and_dial_uniqueid (const char *type, int format, void *data, int timeout, int *outstate, int callingpres, const char *cid_num, const char *cid_name, struct outgoing_helper *oh, char *uniqueid)
int ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params)
int ast_active_channels (void)
 returns number of active/allocated channels
char * ast_alloc_uniqueid (void)
 Create a uniqueid.
int ast_answer (struct ast_channel *chan)
 Answer a ringing call.
void ast_begin_shutdown (int hangup)
 Initiate system shutdown.
int ast_best_codec (int fmts)
 Pick the best audio codec.
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_channelast_get_channel_by_uniqueid_locked (const char *uniqueid)
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. Read a frame.
int ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
int ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
int ast_recvchar (struct ast_channel *chan, int timeout)
 Receives a text character from a channel.
char * ast_recvtext (struct ast_channel *chan, int timeout)
 Receives a text string from a channel Read a string of text from a channel.
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.
ast_channelast_request_and_dial_uniqueid (const char *type, int format, void *data, int timeout, int *outstate, int callingpres, const char *cidnum, const char *cidname, char *uniqueid)
ast_channelast_request_with_uniqueid (const char *type, int format, void *data, int *cause, char *uniqueid)
 Requests a channel.
int ast_safe_sleep (struct ast_channel *chan, int ms)
 Wait 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_send_message (const char *type, void *data, char *to, char *from, char *message, int ispdu)
 "Requests" a channel for sending a message
int ast_senddigit (struct ast_channel *chan, char digit)
 Send a DTMF digit to a channel Send a DTMF digit to a channel.
int ast_senddigit_begin (struct ast_channel *chan, char digit)
int ast_senddigit_end (struct ast_channel *chan, char digit, unsigned int duration)
int ast_sendmessage (struct ast_channel *chan, const char *dest, const char *text, int ispdu)
 Sends message to a channel Write text to a display on 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_setstate_and_callerid (struct ast_channel *chan, enum ast_channel_state state, char *cid_num, char *cid_name)
 Change the state of a channel and the callerid of the calling channel.
int ast_settimeout (struct ast_channel *c, int samples, int(*func)(const void *data), void *data)
int ast_shutting_down (void)
 Returns non-zero if Asterisk is being shut down.
int ast_softhangup (struct ast_channel *chan, int cause)
 Softly hangup up a channel.
int ast_softhangup_nolock (struct ast_channel *chan, int cause)
 Softly hangup up a channel (no channel lock).
char * ast_state2str (enum ast_channel_state 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, const char *uniqueid)
 Helper function to find channels.
const char * channelreloadreason2txt (enum channelreloadreason reason)
 Convert enum channelreloadreason to text string for manager event.
static void clone_variables (struct ast_channel *original, struct ast_channel *clone)
 Clone channel variables from 'clone' channel into 'original' channel.
static char * complete_channeltypes (const char *line, const char *word, int pos, int state)
static char * complete_channeltypes_deprecated (const char *line, const char *word, int pos, int state)
static void 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 91 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 94 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 98 of file channel.c.

Referenced by __ast_read().

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

#define STATE2STR_BUFSIZE   32

Definition at line 87 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 1957 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, 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().

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

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

References __ast_request_and_dial_uniqueid().

Referenced by ast_request_and_dial(), and parkandannounce_exec().

02881 {
02882    return __ast_request_and_dial_uniqueid(type, format, data,
02883       timeout, outstate, 0, cid_num, cid_name, oh, NULL);
02884 }

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

Definition at line 2886 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_with_uniqueid(), 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_request_and_dial(), ast_pbx_outgoing_app_uniqueid(), ast_pbx_outgoing_exten_uniqueid(), and ast_request_and_dial_uniqueid().

02887 {
02888    int dummy_outstate;
02889    int cause = 0;
02890    struct ast_channel *chan;
02891    int res = 0;
02892    int last_subclass = 0;
02893    
02894    if (outstate)
02895       *outstate = 0;
02896    else
02897       outstate = &dummy_outstate;   /* make outstate always a valid pointer */
02898 
02899    chan = ast_request_with_uniqueid(type, format, data, &cause, uniqueid);
02900    if (!chan) {
02901       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
02902       /* compute error and return */
02903       if (cause == AST_CAUSE_BUSY)
02904          *outstate = AST_CONTROL_BUSY;
02905       else if (cause == AST_CAUSE_CONGESTION)
02906          *outstate = AST_CONTROL_CONGESTION;
02907       return NULL;
02908    }
02909 
02910    if (oh) {
02911       if (oh->vars)  
02912          ast_set_variables(chan, oh->vars);
02913       /* XXX why is this necessary, for the parent_channel perhaps ? */
02914       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
02915          ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
02916       if (oh->parent_channel)
02917          ast_channel_inherit_variables(oh->parent_channel, chan);
02918       if (oh->account)
02919          ast_cdr_setaccount(chan, oh->account); 
02920    }
02921    ast_set_callerid(chan, cid_num, cid_name, cid_num);
02922 
02923    
02924 
02925    if (!chan->cdr) { /* up till now, this insertion hasn't been done. Therefore,
02926             to keep from throwing off the basic order of the universe,
02927             we will try to keep this cdr from getting posted. */
02928       chan->cdr = ast_cdr_alloc();
02929       ast_cdr_init(chan->cdr, chan);
02930       ast_cdr_start(chan->cdr);
02931    }
02932    if (ast_call(chan, data, 0)) {   /* ast_call failed... */
02933       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
02934    } else {
02935       res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
02936       while (timeout && chan->_state != AST_STATE_UP) {
02937          struct ast_frame *f;
02938          res = ast_waitfor(chan, timeout);
02939          if (res <= 0) /* error, timeout, or done */
02940             break;
02941          if (timeout > -1)
02942             timeout = res;
02943          f = ast_read(chan);
02944          if (!f) {
02945             *outstate = AST_CONTROL_HANGUP;
02946             res = 0;
02947             break;
02948          }
02949          if (f->frametype == AST_FRAME_CONTROL) {
02950             switch (f->subclass) {
02951             case AST_CONTROL_RINGING:  /* record but keep going */
02952                *outstate = f->subclass;
02953                break;
02954 
02955             case AST_CONTROL_BUSY:
02956             case AST_CONTROL_CONGESTION:
02957             case AST_CONTROL_ANSWER:
02958                *outstate = f->subclass;
02959                timeout = 0;      /* trick to force exit from the while() */
02960                break;
02961 
02962             /* Ignore these */
02963             case AST_CONTROL_PROGRESS:
02964             case AST_CONTROL_PROCEEDING:
02965             case AST_CONTROL_HOLD:
02966             case AST_CONTROL_UNHOLD:
02967             case AST_CONTROL_VIDUPDATE:
02968             case AST_CONTROL_SRCUPDATE:
02969             case -1:       /* Ignore -- just stopping indications */
02970                break;
02971 
02972             default:
02973                ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
02974             }
02975             last_subclass = f->subclass;
02976          }
02977          ast_frfree(f);
02978       }
02979    }
02980 
02981    /* Final fixups */
02982    if (oh) {
02983       if (!ast_strlen_zero(oh->context))
02984          ast_copy_string(chan->context, oh->context, sizeof(chan->context));
02985       if (!ast_strlen_zero(oh->exten))
02986          ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
02987       if (oh->priority) 
02988          chan->priority = oh->priority;
02989    }
02990    if (chan->_state == AST_STATE_UP)
02991       *outstate = AST_CONTROL_ANSWER;
02992 
02993    if (res <= 0) {
02994       if ( AST_CONTROL_RINGING == last_subclass ) 
02995          chan->hangupcause = AST_CAUSE_NO_ANSWER;
02996       if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
02997          ast_cdr_init(chan->cdr, chan);
02998       if (chan->cdr) {
02999          char tmp[256];
03000          snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
03001          ast_cdr_setapp(chan->cdr,"Dial",tmp);
03002          ast_cdr_update(chan);
03003          ast_cdr_start(chan->cdr);
03004          ast_cdr_end(chan->cdr);
03005          /* If the cause wasn't handled properly */
03006          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
03007             ast_cdr_failed(chan->cdr);
03008       }
03009       ast_hangup(chan);
03010       chan = NULL;
03011    }
03012    return chan;
03013 }

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

Activate a given generator

Definition at line 1606 of file channel.c.

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

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

01607 {
01608    int res = 0;
01609 
01610    ast_channel_lock(chan);
01611 
01612    if (chan->generatordata) {
01613       if (chan->generator && chan->generator->release)
01614          chan->generator->release(chan, chan->generatordata);
01615       chan->generatordata = NULL;
01616    }
01617 
01618    ast_prod(chan);
01619    if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
01620       res = -1;
01621    }
01622    
01623    if (!res) {
01624       ast_settimeout(chan, 160, generator_force, chan);
01625       chan->generator = gen;
01626    }
01627 
01628    ast_channel_unlock(chan);
01629 
01630    return res;
01631 }

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns number of active/allocated channels

Definition at line 444 of file channel.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, and channels.

Referenced by quit_handler().

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

char* ast_alloc_uniqueid ( void   ) 

Create a uniqueid.

Definition at line 710 of file channel.c.

References ast_config_AST_SYSTEM_NAME, ast_mainpid, and malloc.

Referenced by action_originate().

00710                                {
00711    char *uniqueid;
00712    uniqueid = malloc(64);
00713    if (!uniqueid) return NULL;
00714    snprintf(uniqueid, 63, "%s-%d-%li.%d", ast_config_AST_SYSTEM_NAME, ast_mainpid, (long)time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
00715    return uniqueid;
00716 }

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 1527 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_autoanswer_login(), ast_bridge_call(), ast_control_streamfile(), ast_pickup_call(), ast_retrieve_call(), auth_exec(), autoanswer_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(), my_pickup_call(), my_pickup_channel(), old_milliwatt_exec(), park_call_exec(), park_exec(), pbx_builtin_answer(), pbx_builtin_background(), pbx_builtin_saycharacters(), pbx_builtin_saydigits(), pbx_builtin_saynumber(), pbx_builtin_sayphonetic(), pickup_do(), playback_exec(), privacy_exec(), read_exec(), run_station(), sayunixtime_exec(), send_waveform_to_channel(), skel_exec(), sla_handle_dial_state_event(), sla_station_exec(), speech_background(), testclient_exec(), testserver_exec(), vm_exec(), vm_execmain(), waitforsilence_exec(), zapateller_exec(), and zapras_exec().

01528 {
01529    int res = 0;
01530    ast_channel_lock(chan);
01531    /* You can't answer an outbound call */
01532    if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
01533       ast_channel_unlock(chan);
01534       return 0;
01535    }
01536    /* Stop if we're a zombie or need a soft hangup */
01537    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01538       ast_channel_unlock(chan);
01539       return -1;
01540    }
01541    switch(chan->_state) {
01542    case AST_STATE_RINGING:
01543    case AST_STATE_RING:
01544       if (chan->tech->answer)
01545          res = chan->tech->answer(chan);
01546       ast_setstate(chan, AST_STATE_UP);
01547       ast_cdr_answer(chan->cdr);
01548       break;
01549    case AST_STATE_UP:
01550       ast_cdr_answer(chan->cdr);
01551       break;
01552    default:
01553       break;
01554    }
01555    chan->visible_indication = 0;
01556    ast_channel_unlock(chan);
01557    return res;
01558 }

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

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

int ast_best_codec ( int  fmts  ) 

Pick the best audio codec.

Pick the best codec

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

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

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

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

G.726 is standard ADPCM, in RFC3551 packing order

G.726 is standard ADPCM, in AAL2 packing order

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

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

iLBC is not too bad

Speex is free, but computationally more expensive than GSM

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

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

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

Definition at line 656 of file channel.c.

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

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

00657 {
00658    /* This just our opinion, expressed in code.  We are asked to choose
00659       the best codec to use, given no information */
00660    int x;
00661    static int prefs[] =
00662    {
00663       /*! Okay, ulaw is used by all telephony equipment, so start with it */
00664       AST_FORMAT_ULAW,
00665       /*! Unless of course, you're a silly European, so then prefer ALAW */
00666       AST_FORMAT_ALAW,
00667       /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */
00668       AST_FORMAT_G722,
00669       /*! Okay, well, signed linear is easy to translate into other stuff */
00670       AST_FORMAT_SLINEAR,
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       /*! Speex is free, but computationally more expensive than GSM */
00683       AST_FORMAT_SPEEX,
00684       /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
00685           to use it */
00686       AST_FORMAT_LPC10,
00687       /*! G.729a is faster than 723 and slightly less expensive */
00688       AST_FORMAT_G729A,
00689       /*! Down to G.723.1 which is proprietary but at least designed for voice */
00690       AST_FORMAT_G723_1,
00691    };
00692 
00693    /* Strip out video */
00694    fmts &= AST_FORMAT_AUDIO_MASK;
00695    
00696    /* Find the first preferred codec in the format given */
00697    for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++)
00698       if (fmts & prefs[x])
00699          return prefs[x];
00700    ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
00701    return 0;
00702 }

struct ast_channel* ast_bridged_channel ( struct ast_channel chan  ) 

Find bridged channel.

Parameters:
chan Current channel

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

03741 {
03742    struct ast_channel *bridged;
03743    bridged = chan->_bridge;
03744    if (bridged && bridged->tech->bridged_channel)
03745       bridged = bridged->tech->bridged_channel(chan, bridged);
03746    return bridged;
03747 }

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 3080 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_uniqueid(), agent_call(), ast_feature_request_and_dial(), attempt_reconnect(), begin_dial(), connect_link(), features_call(), findmeexec(), ring_entry(), rpt(), and wait_for_answer().

03081 {
03082    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
03083       If the remote end does not answer within the timeout, then do NOT hang up, but
03084       return anyway.  */
03085    int res = -1;
03086    /* Stop if we're a zombie or need a soft hangup */
03087    ast_channel_lock(chan);
03088    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03089       if (chan->tech->call)
03090          res = chan->tech->call(chan, addr, timeout);
03091       ast_set_flag(chan, AST_FLAG_OUTGOING);
03092    }
03093    ast_channel_unlock(chan);
03094    return res;
03095 }

void ast_cancel_shutdown ( void   ) 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 456 of file channel.c.

Referenced by handle_abort_halt().

00457 {
00458    shutting_down = 0;
00459 }

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

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

void ast_change_name ( struct ast_channel chan,
char *  newname 
)

Change channel name.

Definition at line 3328 of file channel.c.

References ast_string_field_set, manager_event(), and name.

Referenced by update_name().

03329 {
03330    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
03331    ast_string_field_set(chan, name, newname);
03332 }

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 719 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_autoanswer_login(), ast_masq_hold_call(), ast_masq_park_call(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten_uniqueid(), 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().

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

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 3930 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, IS_DIGITAL, 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, ast_channel::transfercapability, VERBOSE_PREFIX_3, and ast_channel::writeformat.

Referenced by ast_bridge_call().

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

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

References ast_channel::whentohangup.

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

int ast_channel_datastore_add ( struct ast_channel chan,
struct ast_datastore datastore 
)

Add a datastore to a channel.

Definition at line 1345 of file channel.c.

References AST_LIST_INSERT_HEAD.

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

01346 {
01347    int res = 0;
01348 
01349    AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
01350 
01351    return res;
01352 }

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

Create a channel datastore structure.

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

01285 {
01286    struct ast_datastore *datastore = NULL;
01287 
01288    /* Make sure we at least have type so we can identify this */
01289    if (info == NULL) {
01290       return NULL;
01291    }
01292 
01293    /* Allocate memory for datastore and clear it */
01294    datastore = ast_calloc(1, sizeof(*datastore));
01295    if (datastore == NULL) {
01296       return NULL;
01297    }
01298 
01299    datastore->info = info;
01300 
01301    datastore->uid = ast_strdup(uid);
01302 
01303    return datastore;
01304 }

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

01373 {
01374    struct ast_datastore *datastore = NULL;
01375    
01376    if (info == NULL)
01377       return NULL;
01378 
01379    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
01380       if (datastore->info == info) {
01381          if (uid != NULL && datastore->uid != NULL) {
01382             if (!strcasecmp(uid, datastore->uid)) {
01383                /* Matched by type AND uid */
01384                break;
01385             }
01386          } else {
01387             /* Matched by type at least */
01388             break;
01389          }
01390       }
01391    }
01392    AST_LIST_TRAVERSE_SAFE_END
01393 
01394    return datastore;
01395 }

int ast_channel_datastore_free ( struct ast_datastore datastore  ) 

Free a channel datastore structure.

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

01307 {
01308    int res = 0;
01309 
01310    /* Using the destroy function (if present) destroy the data */
01311    if (datastore->info->destroy != NULL && datastore->data != NULL) {
01312       datastore->info->destroy(datastore->data);
01313       datastore->data = NULL;
01314    }
01315 
01316    /* Free allocated UID memory */
01317    if (datastore->uid != NULL) {
01318       free(datastore->uid);
01319       datastore->uid = NULL;
01320    }
01321 
01322    /* Finally free memory used by ourselves */
01323    free(datastore);
01324 
01325    return res;
01326 }

int ast_channel_datastore_inherit ( struct ast_channel from,
struct ast_channel to 
)

Inherit datastores from a parent to a child.

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

01329 {
01330    struct ast_datastore *datastore = NULL, *datastore2;
01331 
01332    AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
01333       if (datastore->inheritance > 0) {
01334          datastore2 = ast_channel_datastore_alloc(datastore->info, datastore->uid);
01335          if (datastore2) {
01336             datastore2->data = datastore->info->duplicate(datastore->data);
01337             datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
01338             AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
01339          }
01340       }
01341    }
01342    return 0;
01343 }

int ast_channel_datastore_remove ( struct ast_channel chan,
struct ast_datastore datastore 
)

Remove a datastore from a channel.

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

01355 {
01356    struct ast_datastore *datastore2 = NULL;
01357    int res = -1;
01358 
01359    /* Find our position and remove ourselves */
01360    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, entry) {
01361       if (datastore2 == datastore) {
01362          AST_LIST_REMOVE_CURRENT(&chan->datastores, entry);
01363          res = 0;
01364          break;
01365       }
01366    }
01367    AST_LIST_TRAVERSE_SAFE_END
01368 
01369    return res;
01370 }

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

References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.

Referenced by __adsi_transmit_messages(), and find_cache().

00986 {
00987    int pre = 0;
00988 
00989    if (chan) {
00990       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
00991       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
00992    }
00993    return pre;
00994 }

void ast_channel_free ( struct ast_channel chan  ) 

Free a channel structure.

Definition at line 1197 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_iax2_new(), ast_pbx_outgoing_cdr_failed(), gtalk_newcall(), local_new(), make_email_file(), pbx_substitute_variables_helper_full(), and sendpage().

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

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

03335 {
03336    struct ast_var_t *current, *newvar;
03337    const char *varname;
03338 
03339    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
03340       int vartype = 0;
03341 
03342       varname = ast_var_full_name(current);
03343       if (!varname)
03344          continue;
03345 
03346       if (varname[0] == '_') {
03347          vartype = 1;
03348          if (varname[1] == '_')
03349             vartype = 2;
03350       }
03351 
03352       switch (vartype) {
03353       case 1:
03354          newvar = ast_var_assign(&varname[1], ast_var_value(current));
03355          if (newvar) {
03356             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03357             if (option_debug)
03358                ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
03359          }
03360          break;
03361       case 2:
03362          newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
03363          if (newvar) {
03364             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03365             if (option_debug)
03366                ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
03367          }
03368          break;
03369       default:
03370          if (option_debug)
03371             ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
03372          break;
03373       }
03374    }
03375 }

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 3187 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(), ast_retrieve_call(), autoanswer_exec(), bridge_exec(), check_compat(), park_exec(), try_calling(), and wait_for_answer().

03188 {
03189    int src;
03190    int dst;
03191 
03192    if (chan->readformat == peer->writeformat && chan->writeformat == peer->readformat) {
03193       /* Already compatible!  Moving on ... */
03194       return 0;
03195    }
03196 
03197    /* Set up translation from the chan to the peer */
03198    src = chan->nativeformats;
03199    dst = peer->nativeformats;
03200    if (ast_translator_best_choice(&dst, &src) < 0) {
03201       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
03202       return -1;
03203    }
03204 
03205    /* if the best path is not 'pass through', then
03206       transcoding is needed; if desired, force transcode path
03207       to use SLINEAR between channels, but only if there is
03208       no direct conversion available */
03209    if ((src != dst) && ast_opt_transcode_via_slin &&
03210        (ast_translate_path_steps(dst, src) != 1))
03211       dst = AST_FORMAT_SLINEAR;
03212    if (ast_set_read_format(chan, dst) < 0) {
03213       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
03214       return -1;
03215    }
03216    if (ast_set_write_format(peer, dst) < 0) {
03217       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", peer->name, dst);
03218       return -1;
03219    }
03220 
03221    /* Set up translation from the peer to the chan */
03222    src = peer->nativeformats;
03223    dst = chan->nativeformats;
03224    if (ast_translator_best_choice(&dst, &src) < 0) {
03225       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", peer->name, src, chan->name, dst);
03226       return -1;
03227    }
03228 
03229    /* if the best path is not 'pass through', then
03230       transcoding is needed; if desired, force transcode path
03231       to use SLINEAR between channels, but only if there is
03232       no direct conversion available */
03233    if ((src != dst) && ast_opt_transcode_via_slin &&
03234        (ast_translate_path_steps(dst, src) != 1))
03235       dst = AST_FORMAT_SLINEAR;
03236    if (ast_set_read_format(peer, dst) < 0) {
03237       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", peer->name, dst);
03238       return -1;
03239    }
03240    if (ast_set_write_format(chan, dst) < 0) {
03241       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", chan->name, dst);
03242       return -1;
03243    }
03244    return 0;
03245 }

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 3247 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_autoanswer_login(), ast_masq_hold_call(), ast_masq_park_call(), ast_pickup_call(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), misdn_transfer_bc(), my_pickup_call(), my_pickup_channel(), pickup_do(), and sip_park().

03248 {
03249    int res = -1;
03250    struct ast_channel *final_orig, *final_clone, *base;
03251 
03252 retrymasq:
03253    final_orig = original;
03254    final_clone = clone;
03255 
03256    ast_channel_lock(original);
03257    while (ast_channel_trylock(clone)) {
03258       ast_channel_unlock(original);
03259       usleep(1);
03260       ast_channel_lock(original);
03261    }
03262 
03263    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
03264       and if so, we don't really want to masquerade it, but its proxy */
03265    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
03266       final_orig = original->_bridge;
03267 
03268    if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)) && (clone->_bridge->_bridge != clone))
03269       final_clone = clone->_bridge;
03270    
03271    if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) {
03272       final_clone = base;
03273    }
03274 
03275    if ((final_orig != original) || (final_clone != clone)) {
03276       /* Lots and lots of deadlock avoidance.  The main one we're competing with
03277        * is ast_write(), which locks channels recursively, when working with a
03278        * proxy channel. */
03279       if (ast_channel_trylock(final_orig)) {
03280          ast_channel_unlock(clone);
03281          ast_channel_unlock(original);
03282          goto retrymasq;
03283       }
03284       if (ast_channel_trylock(final_clone)) {
03285          ast_channel_unlock(final_orig);
03286          ast_channel_unlock(clone);
03287          ast_channel_unlock(original);
03288          goto retrymasq;
03289       }
03290       ast_channel_unlock(clone);
03291       ast_channel_unlock(original);
03292       original = final_orig;
03293       clone = final_clone;
03294    }
03295 
03296    if (original == clone) {
03297       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
03298       ast_channel_unlock(clone);
03299       ast_channel_unlock(original);
03300       return -1;
03301    }
03302 
03303    if (option_debug)
03304       ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
03305          clone->name, original->name);
03306    if (original->masq) {
03307       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03308          original->masq->name, original->name);
03309    } else if (clone->masqr) {
03310       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03311          clone->name, clone->masqr->name);
03312    } else {
03313       original->masq = clone;
03314       clone->masqr = original;
03315       ast_queue_frame(original, &ast_null_frame);
03316       ast_queue_frame(clone, &ast_null_frame);
03317       if (option_debug)
03318          ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
03319       res = 0;
03320    }
03321 
03322    ast_channel_unlock(clone);
03323    ast_channel_unlock(original);
03324 
03325    return res;
03326 }

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

02858 {
02859    switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */
02860    {
02861    case 0:
02862       return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
02863    case AST_CONTROL_HANGUP:
02864       return "Hangup";
02865    case AST_CONTROL_RING:
02866       return "Local Ring";
02867    case AST_CONTROL_RINGING:
02868       return "Remote end Ringing";
02869    case AST_CONTROL_ANSWER:
02870       return "Remote end has Answered";
02871    case AST_CONTROL_BUSY:
02872       return "Remote end is Busy";
02873    case AST_CONTROL_CONGESTION:
02874       return "Congestion (circuits busy)";
02875    default:
02876       return "Unknown Reason!!";
02877    }
02878 }

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

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

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

03176 {
03177    if (chan->tech->send_html)
03178       return chan->tech->send_html(chan, subclass, data, datalen);
03179    return -1;
03180 }

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

References ast_channel_sendhtml(), and AST_HTML_URL.

Referenced by sendurl_exec(), and try_calling().

03183 {
03184    return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
03185 }

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

04203 {
04204    int res;
04205 
04206    if (chan->tech->setoption) {
04207       res = chan->tech->setoption(chan, option, data, datalen);
04208       if (res < 0)
04209          return res;
04210    } else {
04211       errno = ENOSYS;
04212       return -1;
04213    }
04214    if (block) {
04215       /* XXX Implement blocking -- just wait for our option frame reply, discarding
04216          intermediate packets. XXX */
04217       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
04218       return -1;
04219    }
04220    return 0;
04221 }

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

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

Referenced by action_timeout(), and timeout_write().

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

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

04531 {
04532    struct ast_silence_generator *state;
04533 
04534    if (!(state = ast_calloc(1, sizeof(*state)))) {
04535       return NULL;
04536    }
04537 
04538    state->old_write_format = chan->writeformat;
04539 
04540    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
04541       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
04542       free(state);
04543       return NULL;
04544    }
04545 
04546    ast_activate_generator(chan, &silence_generator, state);
04547 
04548    if (option_debug)
04549       ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
04550 
04551    return state;
04552 }

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

04555 {
04556    if (!state)
04557       return;
04558 
04559    ast_deactivate_generator(chan);
04560 
04561    if (option_debug)
04562       ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
04563 
04564    if (ast_set_write_format(chan, state->old_write_format) < 0)
04565       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
04566 
04567    free(state);
04568 }

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

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

Referenced by sendurl_exec(), and try_calling().

03171 {
03172    return (chan->tech->send_html) ? 1 : 0;
03173 }

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

References ast_clear_flag, and AST_FLAG_DEFER_DTMF.

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

00998 {
00999    if (chan)
01000       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
01001 }

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

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

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

References channel_find_locked().

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

01114 {
01115    return channel_find_locked(prev, NULL, 0, NULL, NULL, NULL);
01116 }

void ast_channels_init ( void   ) 

Provided by channel.c

Definition at line 4454 of file channel.c.

References ast_cli_register_multiple(), and cli_channel.

Referenced by main().

04455 {
04456    ast_cli_register_multiple(cli_channel, sizeof(cli_channel) / sizeof(struct ast_cli_entry));
04457 }

struct ast_variable* ast_channeltype_list ( void   ) 

return an ast_variable list of channeltypes

Definition at line 164 of file channel.c.

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

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

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 386 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_sendmessage(), 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_request_invite(), handle_sendimage(), pbx_exec(), rpt(), wait_for_answer(), zt_setoption(), and zt_tdd_sendtext().

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

static int ast_check_hangup_locked ( struct ast_channel chan  )  [static]

Definition at line 400 of file channel.c.

References ast_channel_lock, ast_channel_unlock, and ast_check_hangup().

Referenced by ast_channel_bridge().

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

void ast_deactivate_generator ( struct ast_channel chan  ) 

Deactive an active generator

Definition at line 1560 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(), old_milliwatt_exec(), and wait_for_answer().

01561 {
01562    ast_channel_lock(chan);
01563    if (chan->generatordata) {
01564       if (chan->generator && chan->generator->release)
01565          chan->generator->release(chan, chan->generatordata);
01566       chan->generatordata = NULL;
01567       chan->generator = NULL;
01568       chan->fds[AST_GENERATOR_FD] = -1;
01569       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
01570       ast_settimeout(chan, 0, NULL, NULL);
01571    }
01572    ast_channel_unlock(chan);
01573 }

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

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

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

03786 {
03787    /* Copy voice back and forth between the two channels. */
03788    struct ast_channel *cs[3];
03789    struct ast_frame *f;
03790    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03791    int o0nativeformats;
03792    int o1nativeformats;
03793    int watch_c0_dtmf;
03794    int watch_c1_dtmf;
03795    void *pvt0, *pvt1;
03796    /* Indicates whether a frame was queued into a jitterbuffer */
03797    int frame_put_in_jb = 0;
03798    int jb_in_use;
03799    int to;
03800    
03801    cs[0] = c0;
03802    cs[1] = c1;
03803    pvt0 = c0->tech_pvt;
03804    pvt1 = c1->tech_pvt;
03805    o0nativeformats = c0->nativeformats;
03806    o1nativeformats = c1->nativeformats;
03807    watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
03808    watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
03809 
03810    /* Check the need of a jitterbuffer for each channel */
03811    jb_in_use = ast_jb_do_usecheck(c0, c1);
03812 
03813    for (;;) {
03814       struct ast_channel *who, *other;
03815 
03816       if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
03817           (o0nativeformats != c0->nativeformats) ||
03818           (o1nativeformats != c1->nativeformats)) {
03819          /* Check for Masquerade, codec changes, etc */
03820          res = AST_BRIDGE_RETRY;
03821          break;
03822       }
03823       if (bridge_end.tv_sec) {
03824          to = ast_tvdiff_ms(bridge_end, ast_tvnow());
03825          if (to <= 0) {
03826             if (config->timelimit)
03827                res = AST_BRIDGE_RETRY;
03828             else
03829                res = AST_BRIDGE_COMPLETE;
03830             break;
03831          }
03832       } else
03833          to = -1;
03834       /* Calculate the appropriate max sleep interval - in general, this is the time,
03835          left to the closest jb delivery moment */
03836       if (jb_in_use)
03837          to = ast_jb_get_when_to_wakeup(c0, c1, to);
03838       who = ast_waitfor_n(cs, 2, &to);
03839       if (!who) {
03840          /* No frame received within the specified timeout - check if we have to deliver now */
03841          if (jb_in_use)
03842             ast_jb_get_and_deliver(c0, c1);
03843          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
03844             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03845                c0->_softhangup = 0;
03846             if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03847                c1->_softhangup = 0;
03848             c0->_bridge = c1;
03849             c1->_bridge = c0;
03850          }
03851          continue;
03852       }
03853       f = ast_read(who);
03854       if (!f) {
03855          *fo = NULL;
03856          *rc = who;
03857          if (option_debug)
03858             ast_log(LOG_DEBUG, "Didn't get a frame from channel: %s\n",who->name);
03859          break;
03860       }
03861 
03862       other = (who == c0) ? c1 : c0; /* the 'other' channel */
03863       /* Try add the frame info the who's bridged channel jitterbuff */
03864       if (jb_in_use)
03865          frame_put_in_jb = !ast_jb_put(other, f);
03866 
03867       if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
03868          int bridge_exit = 0;
03869 
03870          switch (f->subclass) {
03871          case AST_CONTROL_HOLD:
03872          case AST_CONTROL_UNHOLD:
03873          case AST_CONTROL_VIDUPDATE:
03874          case AST_CONTROL_SRCUPDATE:
03875             ast_indicate_data(other, f->subclass, f->data, f->datalen);
03876             break;
03877          default:
03878             *fo = f;
03879             *rc = who;
03880             bridge_exit = 1;
03881             if (option_debug)
03882                ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
03883             break;
03884          }
03885          if (bridge_exit)
03886             break;
03887       }
03888       if ((f->frametype == AST_FRAME_VOICE) ||
03889           (f->frametype == AST_FRAME_DTMF_BEGIN) ||
03890           (f->frametype == AST_FRAME_DTMF) ||
03891           (f->frametype == AST_FRAME_VIDEO) ||
03892           (f->frametype == AST_FRAME_IMAGE) ||
03893           (f->frametype == AST_FRAME_HTML) ||
03894           (f->frametype == AST_FRAME_MODEM) ||
03895           (f->frametype == AST_FRAME_TEXT)) {
03896          /* monitored dtmf causes exit from bridge */
03897          int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
03898 
03899          if (monitored_source && 
03900             (f->frametype == AST_FRAME_DTMF_END || 
03901             f->frametype == AST_FRAME_DTMF_BEGIN)) {
03902             *fo = f;
03903             *rc = who;
03904             if (option_debug)
03905                ast_log(LOG_DEBUG, "Got DTMF %s on channel (%s)\n", 
03906                   f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
03907                   who->name);
03908             break;
03909          }
03910          /* Write immediately frames, not passed through jb */
03911          if (!frame_put_in_jb)
03912             ast_write(other, f);
03913             
03914          /* Check if we have to deliver now */
03915          if (jb_in_use)
03916             ast_jb_get_and_deliver(c0, c1);
03917       }
03918       /* XXX do we want to pass on also frames not matched above ? */
03919       ast_frfree(f);
03920 
03921       /* Swap who gets priority */
03922       cs[2] = cs[0];
03923       cs[0] = cs[1];
03924       cs[1] = cs[2];
03925    }
03926    return res;
03927 }

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

References channel_find_locked().

01139 {
01140    return channel_find_locked(NULL, NULL, 0, context, exten, NULL);
01141 }

struct ast_channel* ast_get_channel_by_name_locked ( const char *  name  ) 

Get channel by name (locks channel).

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

01120 {
01121    return channel_find_locked(NULL, name, 0, NULL, NULL, NULL);
01122 }

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

References channel_find_locked().

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

01126 {
01127    return channel_find_locked(NULL, name, namelen, NULL, NULL, NULL);
01128 }

struct ast_channel* ast_get_channel_by_uniqueid_locked ( const char *  uniqueid  ) 

Get channel by uniqueid (locks channel)

Definition at line 1150 of file channel.c.

References channel_find_locked().

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

01151 {
01152    return channel_find_locked(NULL, NULL, 0, NULL, NULL, uniqueid);
01153 }

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

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

ast_group_t ast_get_group ( const char *  s  ) 

Definition at line 4375 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(), pickdown_exec(), pickup_exec(), process_zap(), read_agent_config(), and steal_exec().

04376 {
04377    char *piece;
04378    char *c;
04379    int start=0, finish=0, x;
04380    ast_group_t group = 0;
04381 
04382    if (ast_strlen_zero(s))
04383       return 0;
04384 
04385    c = ast_strdupa(s);
04386    
04387    while ((piece = strsep(&c, ","))) {
04388       if (sscanf(piece, "%d-%d", &start, &finish) == 2) {
04389          /* Range */
04390       } else if (sscanf(piece, "%d", &start)) {
04391          /* Just one */
04392          finish = start;
04393       } else {
04394          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
04395          continue;
04396       }
04397       for (x = start; x <= finish; x++) {
04398          if ((x > 63) || (x < 0)) {
04399             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
04400          } else
04401             group |= ((ast_group_t) 1 << x);
04402       }
04403    }
04404    return group;
04405 }

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

References ast_assert, 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, 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_uniqueid(), __oh323_new(), action_bridge(), agent_hangup(), agent_read(), alsa_new(), answer_exec_run(), app_exec(), ast_async_goto(), ast_autoanswer_login(), ast_bridge_call_thread(), ast_dial_destroy(), ast_dial_hangup(), ast_feature_request_and_dial(), ast_iax2_new(), ast_pbx_outgoing_app_uniqueid(), ast_pbx_outgoing_exten_uniqueid(), ast_pbx_run_app(), ast_retrieve_call(), ast_retrieve_call_to_death(), ast_send_message(), async_wait(), autoanswer_exec(), 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_autoanswer_thread(), do_hang(), do_holding_thread(), do_parking_thread(), features_hangup(), findmeexec(), gtalk_new(), handle_enbloc_call_message(), handle_frame(), handle_frame_ownerless(), handle_hd_hf(), handle_init_event(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_soft_key_event_message(), handle_stimulus_message(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), local_attended_transfer(), local_hangup(), mgcp_new(), mgcp_ss(), monitor_dial(), nbs_new(), oss_new(), park_exec(), parkandannounce_exec(), phone_new(), rpt(), rpt_call(), rpt_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().

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

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

02374 {
02375    return ast_indicate_data(chan, condition, NULL, 0);
02376 }

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

Indicates condition of channel, with payload.

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

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

02379 {
02380    int res = -1;
02381 
02382    ast_channel_lock(chan);
02383    /* Stop if we're a zombie or need a soft hangup */
02384    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02385       ast_channel_unlock(chan);
02386       return -1;
02387    }
02388    if (chan->tech->indicate)
02389       res = chan->tech->indicate(chan, condition, data, datalen);
02390    ast_channel_unlock(chan);
02391    if (!chan->tech->indicate || res) {
02392       /*
02393        * Device does not support (that) indication, lets fake
02394        * it by doing our own tone generation. (PM2002)
02395        */
02396       if (condition < 0)
02397          ast_playtones_stop(chan);
02398       else {
02399          const struct tone_zone_sound *ts = NULL;
02400          switch (condition) {
02401          case AST_CONTROL_RINGING:
02402             ts = ast_get_indication_tone(chan->zone, "ring");
02403             break;
02404          case AST_CONTROL_BUSY:
02405             ts = ast_get_indication_tone(chan->zone, "busy");
02406             break;
02407          case AST_CONTROL_CONGESTION:
02408             ts = ast_get_indication_tone(chan->zone, "congestion");
02409             break;
02410          }
02411          if (ts && ts->data[0]) {
02412             if (option_debug)
02413                ast_log(LOG_DEBUG, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
02414             ast_playtones_start(chan,0,ts->data, 1);
02415             res = 0;
02416             chan->visible_indication = condition;
02417          } else if (condition == AST_CONTROL_PROGRESS) {
02418             /* ast_playtones_stop(chan); */
02419          } else if (condition == AST_CONTROL_PROCEEDING) {
02420             /* Do nothing, really */
02421          } else if (condition == AST_CONTROL_HOLD) {
02422             /* Do nothing.... */
02423          } else if (condition == AST_CONTROL_UNHOLD) {
02424             /* Do nothing.... */
02425          } else if (condition == AST_CONTROL_VIDUPDATE) {
02426             /* Do nothing.... */
02427          } else if (condition == AST_CONTROL_SRCUPDATE) {
02428             /* Do nothing... */
02429          } else {
02430             /* not handled */
02431             ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
02432             res = -1;
02433          }
02434       }
02435    } else
02436       chan->visible_indication = condition;
02437 
02438    return res;
02439 }

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

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by load_module(), and reload().

04414 {
04415    ast_moh_start_ptr = start_ptr;
04416    ast_moh_stop_ptr = stop_ptr;
04417    ast_moh_cleanup_ptr = cleanup_ptr;
04418 }

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

02356 {
02357    int ret = ast_opt_internal_timing && chan->timingfd > -1;
02358    if (option_debug > 4)
02359       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);
02360    return ret;
02361 }

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

References ast_moh_cleanup_ptr.

Referenced by ast_channel_free().

04449 {
04450    if (ast_moh_cleanup_ptr)
04451       ast_moh_cleanup_ptr(chan);
04452 }

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

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

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

04429 {
04430    if (ast_moh_start_ptr)
04431       return ast_moh_start_ptr(chan, mclass, interpclass);
04432 
04433    if (option_verbose > 2) {
04434       ast_verbose(VERBOSE_PREFIX_3 "Music class %s requested but no musiconhold loaded.\n", 
04435          mclass ? mclass : (interpclass ? interpclass : "default"));
04436    }
04437 
04438    return 0;
04439 }

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

References ast_moh_stop_ptr.

Referenced by alsa_indicate(), app_exec(), ast_get_holded_call(), ast_quiet_chan(), ast_retrieve_call(), autoanswer_exec(), 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(), try_calling(), and zt_indicate().

04443 {
04444    if (ast_moh_stop_ptr)
04445       ast_moh_stop_ptr(chan);
04446 }

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

print call- and pickup groups into buffer

Definition at line 4460 of file channel.c.

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

04461 {
04462    unsigned int i;
04463    int first=1;
04464    char num[3];
04465 
04466    buf[0] = '\0';
04467    
04468    if (!group) /* Return empty string if no group */
04469       return buf;
04470 
04471    for (i = 0; i <= 63; i++) {   /* Max group is 63 */
04472       if (group & ((ast_group_t) 1 << i)) {
04473             if (!first) {
04474             strncat(buf, ", ", buflen - strlen(buf) - 1);
04475          } else {
04476             first=0;
04477          }
04478          snprintf(num, sizeof(num), "%u", i);
04479          strncat(buf, num, buflen - strlen(buf) - 1);
04480       }
04481    }
04482    return buf;
04483 }

int ast_prod ( struct ast_channel chan  ) 

Send empty audio to prime a channel driver.

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

02577 {
02578    struct ast_frame a = { AST_FRAME_VOICE };
02579    char nothing[128];
02580 
02581    /* Send an empty audio frame to get things moving */
02582    if (chan->_state != AST_STATE_UP) {
02583       if (option_debug)
02584          ast_log(LOG_DEBUG, "Prodding channel '%s'\n", chan->name);
02585       a.subclass = chan->rawwriteformat;
02586       a.data = nothing + AST_FRIENDLY_OFFSET;
02587       a.src = "ast_prod";
02588       if (ast_write(chan, &a))
02589          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
02590    }
02591    return 0;
02592 }

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

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

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

00974 {
00975    struct ast_frame f = { AST_FRAME_CONTROL, };
00976 
00977    f.subclass = control;
00978    f.data = (void *) data;
00979    f.datalen = datalen;
00980 
00981    return ast_queue_frame(chan, &f);
00982 }

int ast_queue_frame ( struct ast_channel chan,
struct ast_frame fin 
)

Queue an outgoing frame.

Definition at line 894 of file channel.c.

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

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

int ast_queue_hangup ( struct ast_channel chan  ) 

Queue a hangup frame.

Definition at line 950 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(), gtalk_is_answered(), handle_onhook_message(), handle_request_bye(), handle_request_cancel(), handle_response(), handle_response_invite(), handle_soft_key_event_message(), hangup_chan(), hangup_connection(), iax2_destroy(), iax2_queue_hangup(), mgcp_queue_hangup(), misdn_answer(), retrans_pkt(), and zt_handle_event().

00951 {
00952    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
00953    /* Yeah, let's not change a lock-critical value without locking */
00954    if (!ast_channel_trylock(chan)) {
00955       chan->_softhangup |= AST_SOFTHANGUP_DEV;
00956       ast_channel_unlock(chan);
00957    }
00958    return ast_queue_frame(chan, &f);
00959 }

struct ast_frame* ast_read ( struct ast_channel chan  ) 

Reads a frame.

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

Definition at line 2363 of file channel.c.

References __ast_read().

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

02364 {
02365    return __ast_read(chan, 0);
02366 }

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

Definition at line 1903 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_deactivate_generator(), ast_format_rate(), 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, ast_channel::timingfunc, and ast_channel::writeformat.

Referenced by __ast_read().

01904 {
01905    if (chan->generatordata &&  !ast_internal_timing_enabled(chan)) {
01906       void *tmp = chan->generatordata;
01907       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
01908       int res;
01909       int samples;
01910 
01911       if (chan->timingfunc) {
01912          if (option_debug > 1)
01913             ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
01914          ast_settimeout(chan, 0, NULL, NULL);
01915       }
01916 
01917       chan->generatordata = NULL;     /* reset, to let writes go through */
01918 
01919       if (f->subclass != chan->writeformat) {
01920          float factor;
01921          factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass));
01922          samples = (int) ( ((float) f->samples) * factor );
01923       } else {
01924          samples = f->samples;
01925       }
01926 
01927       if (chan->generator->generate) {
01928          generate = chan->generator->generate;
01929       }
01930       /* This unlock is here based on two assumptions that hold true at this point in the
01931        * code. 1) this function is only called from within __ast_read() and 2) all generators
01932        * call ast_write() in their generate callback.
01933        *
01934        * The reason this is added is so that when ast_write is called, the lock that occurs 
01935        * there will not recursively lock the channel. Doing this will cause intended deadlock 
01936        * avoidance not to work in deeper functions
01937        */
01938       ast_channel_unlock(chan);
01939       res = generate(chan, tmp, f->datalen, samples);
01940       ast_channel_lock(chan);
01941       chan->generatordata = tmp;
01942       if (res) {
01943          if (option_debug > 1)
01944             ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01945          ast_deactivate_generator(chan);
01946       }
01947 
01948    } else if (f->frametype == AST_FRAME_CNG) {
01949       if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
01950          if (option_debug > 1)
01951             ast_log(LOG_DEBUG, "Generator got CNG, switching to timed mode\n");
01952          ast_settimeout(chan, 160, generator_force, chan);
01953       }
01954    }
01955 }

struct ast_frame* ast_read_noaudio ( struct ast_channel chan  ) 

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

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

Definition at line 2368 of file channel.c.

References __ast_read().

Referenced by conf_run().

02369 {
02370    return __ast_read(chan, 1);
02371 }

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

03123 {
03124    return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
03125 }

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

03128 {
03129    int pos = 0;   /* index in the buffer where we accumulate digits */
03130    int to = ftimeout;
03131 
03132    /* Stop if we're a zombie or need a soft hangup */
03133    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
03134       return -1;
03135    if (!len)
03136       return -1;
03137    for (;;) {
03138       int d;
03139       if (c->stream) {
03140          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
03141          ast_stopstream(c);
03142          usleep(1000);
03143          if (!d)
03144             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03145       } else {
03146          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
03147       }
03148       if (d < 0)
03149          return -1;
03150       if (d == 0) {
03151          s[pos]='\0';
03152          return 1;
03153       }
03154       if (d == 1) {
03155          s[pos]='\0';
03156          return 2;
03157       }
03158       if (!strchr(enders, d))
03159          s[pos++] = d;
03160       if (strchr(enders, d) || (pos >= len)) {
03161          s[pos]='\0';
03162          return 0;
03163       }
03164       to = timeout;
03165    }
03166    /* Never reached */
03167    return 0;
03168 }

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

References ast_recvtext(), and free.

Referenced by handle_recvchar().

02442 {
02443    int c;
02444    char *buf = ast_recvtext(chan, timeout);
02445    if (buf == NULL)
02446       return -1;  /* error or timeout */
02447    c = *(unsigned char *)buf;
02448    free(buf);
02449    return c;
02450 }

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

02453 {
02454    int res, done = 0;
02455    char *buf = NULL;
02456    
02457    while (!done) {
02458       struct ast_frame *f;
02459       if (ast_check_hangup(chan))
02460          break;
02461       res = ast_waitfor(chan, timeout);
02462       if (res <= 0) /* timeout or error */
02463          break;
02464       timeout = res; /* update timeout */
02465       f = ast_read(chan);
02466       if (f == NULL)
02467          break; /* no frame */
02468       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
02469          done = 1;   /* force a break */
02470       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
02471          buf = ast_strndup((char *) f->data, f->datalen);   /* dup and break */
02472          done = 1;
02473       }
02474       ast_frfree(f);
02475    }
02476    return buf;
02477 }

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

References ast_request_with_uniqueid().

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

03076 {
03077     return ast_request_with_uniqueid(type, format, data, cause, NULL);
03078 }

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

References __ast_request_and_dial().

03016 {
03017    return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
03018 }

struct ast_channel* ast_request_and_dial_uniqueid ( const char *  type,
int  format,
void *  data,
int  timeout,
int *  outstate,
int  callingpres,
const char *  cidnum,
const char *  cidname,
char *  uniqueid 
)

Definition at line 3019 of file channel.c.

References __ast_request_and_dial_uniqueid().

Referenced by ast_pbx_outgoing_exten_uniqueid().

03020 {
03021    return __ast_request_and_dial_uniqueid(type, format, data, timeout, outstate, 0, cidnum, cidname, NULL, uniqueid);
03022 }

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

Requests a channel.

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

Definition at line 3024 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_uniqueid(), and ast_request().

03025 {
03026    struct chanlist *chan;
03027    struct ast_channel *c;
03028    int capabilities;
03029    int fmt;
03030    int res;
03031    int foo;
03032    int videoformat = format & AST_FORMAT_VIDEO_MASK;
03033 
03034    if (!cause)
03035       cause = &foo;
03036    *cause = AST_CAUSE_NOTDEFINED;
03037 
03038    if (AST_LIST_LOCK(&channels)) {
03039       ast_log(LOG_WARNING, "Unable to lock channel list\n");
03040       return NULL;
03041    }
03042 
03043    AST_LIST_TRAVERSE(&backends, chan, list) {
03044       if (strcasecmp(type, chan->tech->type))
03045          continue;
03046 
03047       capabilities = chan->tech->capabilities;
03048       fmt = format & AST_FORMAT_AUDIO_MASK;
03049       res = ast_translator_best_choice(&fmt, &capabilities);
03050       if (res < 0) {
03051          ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %d) to %d\n", type, chan->tech->capabilities, format);
03052          *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03053          AST_LIST_UNLOCK(&channels);
03054          return NULL;
03055       }
03056       AST_LIST_UNLOCK(&channels);
03057       if (!chan->tech->requester)
03058          return NULL;
03059       
03060       if (!(c = chan->tech->requester(type, capabilities | videoformat, data, cause)))
03061          return NULL;
03062 
03063       if (uniqueid) strncpy(c->uniqueid, uniqueid, sizeof(c->uniqueid));
03064       /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
03065       return c;
03066    }
03067 
03068    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
03069    *cause = AST_CAUSE_NOSUCHDRIVER;
03070    AST_LIST_UNLOCK(&channels);
03071 
03072    return NULL;
03073 }

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 1177 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(), old_milliwatt_exec(), park_call_exec(), pbx_builtin_answer(), pbx_builtin_wait(), play_tone_pair(), playtone(), privacy_exec(), receive_ademco_contact_id(), rpt_call(), rpt_exec(), rpt_tele_thread(), send_morse(), send_tone_telemetry(), skinny_ss(), ss_thread(), testclient_exec(), testserver_exec(), try_calling(), wait_for_hangup(), wait_interval(), and zapateller_exec().

01178 {
01179    return ast_safe_sleep_conditional(chan, ms, NULL, NULL);
01180 }

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

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

Referenced by __login_exec(), and ast_safe_sleep().

01157 {
01158    struct ast_frame *f;
01159 
01160    while (ms > 0) {
01161       if (cond && ((*cond)(data) == 0))
01162          return 0;
01163       ms = ast_waitfor(chan, ms);
01164       if (ms < 0)
01165          return -1;
01166       if (ms > 0) {
01167          f = ast_read(chan);
01168          if (!f)
01169             return -1;
01170          ast_frfree(f);
01171       }
01172    }
01173    return 0;
01174 }

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

References ast_malloc, and len.

Referenced by features_new(), and zt_new().

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

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

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

04763 {
04764         return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
04765 }

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

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

04757 {
04758         return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
04759 }

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

Definition at line 4749 of file channel.c.

References ast_say_digits_full().

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

04751 {
04752         return ast_say_digits_full(chan, num, ints, lang, -1, -1);
04753 }

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

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

04775 {
04776         char buf[256];
04777 
04778         snprintf(buf, sizeof(buf), "%d", num);
04779         return ast_say_digit_str_full(chan, buf, ints, lang, audiofd, ctrlfd);
04780 }

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

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

04745 {
04746         return ast_say_enumeration_full(chan, num, ints, language, options, -1, -1);
04747 }

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

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

04739 {
04740         return ast_say_number_full(chan, num, ints, language, options, -1, -1);
04741 }

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

Definition at line 4767 of file channel.c.

References ast_say_phonetic_str_full.

Referenced by pbx_builtin_sayphonetic().

04769 {
04770         return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
04771 }

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

"Requests" a channel for sending a message

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

Definition at line 4571 of file channel.c.

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

Referenced by action_message(), and attempt_thread().

04571                                                                                                    {
04572    struct ast_channel *chan = NULL;
04573    int status;
04574    int res = -1;
04575 
04576    chan = ast_request(type, AST_FORMAT_SLINEAR, data, &status);
04577    if (chan) {
04578        if (from) {
04579       ast_set_callerid(chan, from, from, from);
04580        }
04581        res = ast_sendmessage(chan, to, message, ispdu);
04582        /* XXX what about message CDRs ??? XXX */
04583        ast_hangup(chan);
04584        return res;
04585    }
04586 
04587    return res;
04588 }

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

02567 {
02568    if (chan->tech->send_digit_begin) {
02569       ast_senddigit_begin(chan, digit);
02570       ast_safe_sleep(chan, AST_DEFAULT_EMULATE_DTMF_DURATION);
02571    }
02572    
02573    return ast_senddigit_end(chan, digit, AST_DEFAULT_EMULATE_DTMF_DURATION);
02574 }

int ast_senddigit_begin ( struct ast_channel chan,
char  digit 
)

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

02508 {
02509    /* Device does not support DTMF tones, lets fake
02510     * it by doing our own generation. */
02511    static const char* dtmf_tones[] = {
02512       "941+1336", /* 0 */
02513       "697+1209", /* 1 */
02514       "697+1336", /* 2 */
02515       "697+1477", /* 3 */
02516       "770+1209", /* 4 */
02517       "770+1336", /* 5 */
02518       "770+1477", /* 6 */
02519       "852+1209", /* 7 */
02520       "852+1336", /* 8 */
02521       "852+1477", /* 9 */
02522       "697+1633", /* A */
02523       "770+1633", /* B */
02524       "852+1633", /* C */
02525       "941+1633", /* D */
02526       "941+1209", /* * */
02527       "941+1477"  /* # */
02528    };
02529 
02530    if (!chan->tech->send_digit_begin)
02531       return 0;
02532 
02533    if (!chan->tech->send_digit_begin(chan, digit))
02534       return 0;
02535 
02536    if (digit >= '0' && digit <='9')
02537       ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
02538    else if (digit >= 'A' && digit <= 'D')
02539       ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
02540    else if (digit == '*')
02541       ast_playtones_start(chan, 0, dtmf_tones[14], 0);
02542    else if (digit == '#')
02543       ast_playtones_start(chan, 0, dtmf_tones[15], 0);
02544    else {
02545       /* not handled */
02546       if (option_debug)
02547          ast_log(LOG_DEBUG, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
02548    }
02549 
02550    return 0;
02551 }

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

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

02554 {
02555    int res = -1;
02556 
02557    if (chan->tech->send_digit_end)
02558       res = chan->tech->send_digit_end(chan, digit, duration);
02559 
02560    if (res && chan->generator)
02561       ast_playtones_stop(chan);
02562    
02563    return 0;
02564 }

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

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

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

Definition at line 2492 of file channel.c.

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

Referenced by ast_send_message().

02493 {
02494    int res = 0;
02495    /* Stop if we're a zombie or need a soft hangup */
02496    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02497       return -1;
02498    CHECK_BLOCKING(chan);
02499 #if 0 /* we (Debian) disable that addition because of ABI breakage */
02500    if (chan->tech->send_message)
02501       res = chan->tech->send_message(chan, dest, text, ispdu);
02502 #endif
02503    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02504    return res;
02505 }

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

02480 {
02481    int res = 0;
02482    /* Stop if we're a zombie or need a soft hangup */
02483    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02484       return -1;
02485    CHECK_BLOCKING(chan);
02486    if (chan->tech->send_text)
02487       res = chan->tech->send_text(chan, text);
02488    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02489    return res;
02490 }

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 3671 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_uniqueid(), agent_call(), ast_feature_request_and_dial(), ast_send_message(), callerid_write(), disa_exec(), findmeexec(), handle_setcallerid(), lookupcidname_exec(), mgcp_ss(), privacy_exec(), read_config(), setcallerid_exec(), skinny_newcall(), ss_thread(), wait_for_answer(), and zt_read().

03672 {
03673    ast_channel_lock(chan);
03674 
03675    if (callerid) {
03676       if (chan->cid.cid_num)
03677          free(chan->cid.cid_num);
03678       chan->cid.cid_num = ast_strdup(callerid);
03679    }
03680    if (calleridname) {
03681       if (chan->cid.cid_name)
03682          free(chan->cid.cid_name);
03683       chan->cid.cid_name = ast_strdup(calleridname);
03684    }
03685    if (ani) {
03686       if (chan->cid.cid_ani)
03687          free(chan->cid.cid_ani);
03688       chan->cid.cid_ani = ast_strdup(ani);
03689    }
03690    if (chan->cdr)
03691       ast_cdr_setcid(chan->cdr, chan);
03692    manager_event(EVENT_FLAG_CALL, "Newcallerid",
03693             "Channel: %s\r\n"
03694             "CallerID: %s\r\n"
03695             "CallerIDName: %s\r\n"
03696             "Uniqueid: %s\r\n"
03697             "CID-CallingPres: %d (%s)\r\n",
03698             chan->name,
03699             S_OR(chan->cid.cid_num, "<Unknown>"),
03700             S_OR(chan->cid.cid_name, "<Unknown>"),
03701             chan->uniqueid,
03702             chan->cid.cid_pres,
03703             ast_describe_caller_presentation(chan->cid.cid_pres)
03704             );
03705    
03706    ast_channel_unlock(chan);
03707 }

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

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

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

02846 {
02847    return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
02848            &chan->readtrans, 0);
02849 }

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 4485 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_uniqueid(), ast_pbx_outgoing_app_uniqueid(), and ast_pbx_outgoing_exten_uniqueid().

04486 {
04487    struct ast_variable *cur;
04488 
04489    for (cur = vars; cur; cur = cur->next)
04490       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
04491 }

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

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

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

02852 {
02853    return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
02854            &chan->writetrans, 1);
02855 }

int ast_setstate ( struct ast_channel chan,
enum ast_channel_state  state 
)

Change the state of a channel.

Definition at line 3734 of file channel.c.

References ast_setstate_and_callerid().

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

03735 {
03736     return ast_setstate_and_callerid(chan, state, NULL, NULL);
03737 }

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

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

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

03710 {
03711    int oldstate = chan->_state;
03712 
03713    if (oldstate == state)
03714       return 0;
03715 
03716    chan->_state = state;
03717    ast_device_state_changed_literal(chan->name, cid_num, cid_name);
03718    /* setstate used to conditionally report Newchannel; this is no more */
03719    manager_event(EVENT_FLAG_CALL,
03720             "Newstate",
03721             "Channel: %s\r\n"
03722             "State: %s\r\n"
03723             "CallerID: %s\r\n"
03724             "CallerIDName: %s\r\n"
03725             "Uniqueid: %s\r\n",
03726             chan->name, ast_state2str(chan->_state),
03727             S_OR(chan->cid.cid_num, "<unknown>"),
03728             S_OR(chan->cid.cid_name, "<unknown>"),
03729             chan->uniqueid);
03730 
03731    return 0;
03732 }

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

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

01812 {
01813    int res = -1;
01814 #ifdef HAVE_ZAPTEL
01815    if (c->timingfd > -1) {
01816       if (!func) {
01817          samples = 0;
01818          data = 0;
01819       }
01820       if (option_debug)
01821          ast_log(LOG_DEBUG, "Scheduling timer at %d sample intervals\n", samples);
01822       res = ioctl(c->timingfd, ZT_TIMERCONFIG, &samples);
01823       c->timingfunc = func;
01824       c->timingdata = data;
01825    }
01826 #endif   
01827    return res;
01828 }

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

Referenced by handle_request_options().

00463 {
00464    return shutting_down;
00465 }

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

01413 {
01414    int res;
01415    ast_channel_lock(chan);
01416    res = ast_softhangup_nolock(chan, cause);
01417    ast_channel_unlock(chan);
01418    return res;
01419 }

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

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

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

01399 {
01400    if (option_debug)
01401       ast_log(LOG_DEBUG, "Soft-Hanging up channel '%s'\n", chan->name);
01402    /* Inform channel driver that we need to be hung up, if it cares */
01403    chan->_softhangup |= cause;
01404    ast_queue_frame(chan, &ast_null_frame);
01405    /* Interrupt any poll call or such */
01406    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
01407       pthread_kill(chan->blocker, SIGURG);
01408    return 0;
01409 }

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

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

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

References causes.

Referenced by pbx_builtin_hangup().

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

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

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

Referenced by zapateller_exec().

04358 {
04359    int res;
04360 
04361    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
04362       return res;
04363 
04364    /* Give us some wiggle room */
04365    while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
04366       struct ast_frame *f = ast_read(chan);
04367       if (f)
04368          ast_frfree(f);
04369       else
04370          return -1;
04371    }
04372    return 0;
04373 }

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

Start a tone going

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

04340 {
04341    struct tonepair_def d = { 0, };
04342 
04343    d.freq1 = freq1;
04344    d.freq2 = freq2;
04345    d.duration = duration;
04346    d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */
04347    if (ast_activate_generator(chan, &tonepair, &d))
04348       return -1;
04349    return 0;
04350 }

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 4352 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

04353 {
04354    ast_deactivate_generator(chan);
04355 }

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

03105 {
03106    int res = -1;
03107 
03108    /* Stop if we're a zombie or need a soft hangup */
03109    ast_channel_lock(chan);
03110    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
03111       if (chan->tech->transfer) {
03112          res = chan->tech->transfer(chan, dest);
03113          if (!res)
03114             res = 1;
03115       } else
03116          res = 0;
03117    }
03118    ast_channel_unlock(chan);
03119    return res;
03120 }

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

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

void ast_uninstall_music_functions ( void   ) 

Definition at line 4420 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by unload_module().

04421 {
04422    ast_moh_start_ptr = NULL;
04423    ast_moh_stop_ptr = NULL;
04424    ast_moh_cleanup_ptr = NULL;
04425 }

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

References ast_waitfor_nandfds().

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

01796 {
01797    int oldms = ms;   /* -1 if no timeout */
01798 
01799    ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
01800    if ((ms < 0) && (oldms < 0))
01801       ms = 0;
01802    return ms;
01803 }

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

01791 {
01792    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
01793 }

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

References ast_waitfor_nandfds().

Referenced by dundi_lookup_internal(), and dundi_precache_internal().

01635 {
01636    int winner = -1;
01637    ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
01638    return winner;
01639 }

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

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

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

References ast_waitfordigit_full().

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

01807 {
01808    return ast_waitfordigit_full(c, ms, -1, -1);
01809 }

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

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

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

References channel_find_locked().

Referenced by next_channel().

01146 {
01147    return channel_find_locked(chan, NULL, 0, context, exten, NULL);
01148 }

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

References channel_find_locked().

Referenced by next_channel().

01133 {
01134    return channel_find_locked(chan, name, namelen, NULL, NULL, NULL);
01135 }

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 2605 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, 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(), NBScat_exec(), rpt(), run_agi(), send_link_dtmf(), send_tone_burst(), send_waveform_to_channel(), silence_generator_generate(), spy_generate(), wait_for_answer(), and zt_bridge().

02606 {
02607    int res = -1;
02608    int count = 0;
02609    struct ast_frame *f = NULL, *f2 = NULL;
02610 
02611    /*Deadlock avoidance*/
02612    while(ast_channel_trylock(chan)) {
02613       /*cannot goto done since the channel is not locked*/
02614       if(count++ > 10) {
02615          if(option_debug)
02616             ast_log(LOG_DEBUG, "Deadlock avoided for write to channel '%s'\n", chan->name);
02617          return 0;
02618       }
02619       usleep(1);
02620    }
02621    /* Stop if we're a zombie or need a soft hangup */
02622    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
02623       goto done;
02624 
02625    /* Handle any pending masquerades */
02626    if (chan->masq && ast_do_masquerade(chan)) {
02627       ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02628       goto done;
02629    }
02630    if (chan->masqr) {
02631       res = 0; /* XXX explain, why 0 ? */
02632       goto done;
02633    }
02634    if (chan->generatordata) {
02635       if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
02636          ast_deactivate_generator(chan);
02637       else {
02638          if (fr->frametype == AST_FRAME_DTMF_END) {
02639             /* There is a generator running while we're in the middle of a digit.
02640              * It's probably inband DTMF, so go ahead and pass it so it can
02641              * stop the generator */
02642             ast_clear_flag(chan, AST_FLAG_BLOCKING);
02643             ast_channel_unlock(chan);
02644             res = ast_senddigit_end(chan, fr->subclass, fr->len);
02645             ast_channel_lock(chan);
02646             CHECK_BLOCKING(chan);
02647          } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass == AST_CONTROL_UNHOLD) {
02648             /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */
02649             res = (chan->tech->indicate == NULL) ? 0 :
02650                chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
02651          }
02652          res = 0; /* XXX explain, why 0 ? */
02653          goto done;
02654       }
02655    }
02656    /* High bit prints debugging */
02657    if (chan->fout & DEBUGCHAN_FLAG)
02658       ast_frame_dump(chan->name, fr, ">>");
02659    CHECK_BLOCKING(chan);
02660    switch(fr->frametype) {
02661    case AST_FRAME_CONTROL:
02662       res = (chan->tech->indicate == NULL) ? 0 :
02663          chan->tech->indicate(chan, fr->subclass, fr->data, fr->datalen);
02664       break;
02665    case AST_FRAME_DTMF_BEGIN:
02666       if (chan->audiohooks) {
02667          struct ast_frame *old_frame = fr;
02668          fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02669          if (old_frame != fr)
02670             f = fr;
02671       }
02672       ast_clear_flag(chan, AST_FLAG_BLOCKING);
02673       ast_channel_unlock(chan);
02674       res = ast_senddigit_begin(chan, fr->subclass);
02675       ast_channel_lock(chan);
02676       CHECK_BLOCKING(chan);
02677       break;
02678    case AST_FRAME_DTMF_END:
02679       if (chan->audiohooks) {
02680          struct ast_frame *old_frame = fr;
02681          fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02682          if (old_frame != fr)
02683             f = fr;
02684       }
02685       ast_clear_flag(chan, AST_FLAG_BLOCKING);
02686       ast_channel_unlock(chan);
02687       res = ast_senddigit_end(chan, fr->subclass, fr->len);
02688       ast_channel_lock(chan);
02689       CHECK_BLOCKING(chan);
02690       break;
02691    case AST_FRAME_TEXT:
02692       res = (chan->tech->send_text == NULL) ? 0 :
02693          chan->tech->send_text(chan, (char *) fr->data);
02694       break;
02695    case AST_FRAME_HTML:
02696       res = (chan->tech->send_html == NULL) ? 0 :
02697          chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
02698       break;
02699    case AST_FRAME_VIDEO:
02700       /* XXX Handle translation of video codecs one day XXX */
02701       res = (chan->tech->write_video == NULL) ? 0 :
02702          chan->tech->write_video(chan, fr);
02703       break;
02704    case AST_FRAME_MODEM:
02705       res = (chan->tech->write == NULL) ? 0 :
02706          chan->tech->write(chan, fr);
02707       break;
02708    case AST_FRAME_VOICE:
02709       if (chan->tech->write == NULL)
02710          break;   /*! \todo XXX should return 0 maybe ? */
02711 
02712       if (chan->audiohooks) {
02713          struct ast_frame *old_frame = fr;
02714          fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
02715          if (old_frame != fr)
02716             f2 = fr;
02717       }
02718       
02719       /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
02720       if (fr->subclass == chan->rawwriteformat)
02721          f = fr;
02722       else
02723          f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
02724 
02725       /* If we have no frame of audio, then we have to bail out */
02726       if (!f) {
02727          res = 0;
02728          break;
02729       }
02730 
02731       /* If Monitor is running on this channel, then we have to write frames out there too */
02732       if (chan->monitor && chan->monitor->write_stream) {
02733          /* XXX must explain this code */
02734 #ifndef MONITOR_CONSTANT_DELAY
02735          int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
02736          if (jump >= 0) {
02737             jump = chan->insmpl - chan->outsmpl;
02738             if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
02739                ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02740             chan->outsmpl += jump + f->samples;
02741          } else
02742             chan->outsmpl += f->samples;
02743 #else
02744          int jump = chan->insmpl - chan->outsmpl;
02745          if (jump - MONITOR_DELAY >= 0) {
02746             if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02747                ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
02748             chan->outsmpl += jump;
02749          } else
02750             chan->outsmpl += f->samples;
02751 #endif
02752          if (chan->monitor->state == AST_MONITOR_RUNNING) {
02753             if (ast_writestream(chan->monitor->write_stream, f) < 0)
02754                ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
02755          }
02756       }
02757 
02758       if (f) 
02759          res = chan->tech->write(chan,f);
02760       else
02761          res = 0;
02762       break;
02763    case AST_FRAME_NULL:
02764    case AST_FRAME_IAX:
02765       /* Ignore these */
02766       res = 0;
02767       break;
02768    default:
02769       /* At this point, fr is the incoming frame and f is NULL.  Channels do
02770        * not expect to get NULL as a frame pointer and will segfault.  Hence,
02771        * we output the original frame passed in. */
02772       res = chan->tech->write(chan, fr);
02773       break;
02774    }
02775 
02776    if (f && f != fr)
02777       ast_frfree(f);
02778    if (f2)
02779       ast_frfree(f2);
02780    ast_clear_flag(chan, AST_FLAG_BLOCKING);
02781    /* Consider a write failure to force a soft hangup */
02782    if (res < 0)
02783       chan->_softhangup |= AST_SOFTHANGUP_DEV;
02784    else {
02785       chan->fout = FRAMECOUNT_INC(chan->fout);
02786    }
02787 done:
02788    ast_channel_unlock(chan);
02789    return res;
02790 }

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

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

02595 {
02596    int res;
02597    if (!chan->tech->write_video)
02598       return 0;
02599    res = ast_write(chan, fr);
02600    if (!res)
02601       res = 1;
02602    return res;
02603 }

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

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

03750 {
03751    int min = 0, sec = 0, check;
03752 
03753    check = ast_autoservice_start(peer);
03754    if (check)
03755       return;
03756 
03757    if (remain > 0) {
03758       if (remain / 60 > 1) {
03759          min = remain / 60;
03760          sec = remain % 60;
03761       } else {
03762          sec = remain;
03763       }
03764    }
03765    
03766    if (!strcmp(sound,"timeleft")) { /* Queue support */
03767       ast_stream_and_wait(chan, "vm-youhave", chan->language, "");
03768       if (min) {
03769          ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
03770          ast_stream_and_wait(chan, "queue-minutes", chan->language, "");
03771       }
03772       if (sec) {
03773          ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
03774          ast_stream_and_wait(chan, "queue-seconds", chan->language, "");
03775       }
03776    } else {
03777       ast_stream_and_wait(chan, sound, chan->language, "");
03778    }
03779 
03780    ast_autoservice_stop(peer);
03781 }

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

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

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

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

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

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

References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.

04592 {
04593    switch (reason) {
04594    case CHANNEL_MODULE_LOAD:
04595       return "LOAD (Channel module load)";
04596 
04597    case CHANNEL_MODULE_RELOAD:
04598       return "RELOAD (Channel module reload)";
04599 
04600    case CHANNEL_CLI_RELOAD:
04601       return "CLIRELOAD (Channel module reload by CLI command)";
04602 
04603    default:
04604       return "MANAGERRELOAD (Channel module reload by manager)";
04605    }
04606 };

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

03387 {
03388    struct ast_var_t *current, *newvar;
03389    /* Append variables from clone channel into original channel */
03390    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
03391    if (AST_LIST_FIRST(&clone->varshead))
03392       AST_LIST_APPEND_LIST(&original->varshead, &clone->varshead, entries);
03393 
03394    /* then, dup the varshead list into the clone */
03395    
03396    AST_LIST_TRAVERSE(&original->varshead, current, entries) {
03397       newvar = ast_var_assign(current->name, current->value);
03398       if (newvar)
03399          AST_LIST_INSERT_TAIL(&clone->varshead, newvar, entries);
03400    }
03401 }

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

Definition at line 335 of file channel.c.

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

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

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

Definition at line 313 of file channel.c.

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

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

static void free_cid ( struct ast_callerid cid  )  [static]

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

01183 {
01184    if (cid->cid_dnid)
01185       free(cid->cid_dnid);
01186    if (cid->cid_num)
01187       free(cid->cid_num);  
01188    if (cid->cid_name)
01189       free(cid->cid_name); 
01190    if (cid->cid_ani)
01191       free(cid->cid_ani);
01192    if (cid->cid_rdnis)
01193       free(cid->cid_rdnis);
01194 }

static void free_translation ( struct ast_channel clone  )  [static]

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

01422 {
01423    if (clone->writetrans)
01424       ast_translator_free_path(clone->writetrans);
01425    if (clone->readtrans)
01426       ast_translator_free_path(clone->readtrans);
01427    clone->writetrans = NULL;
01428    clone->readtrans = NULL;
01429    clone->rawwriteformat = clone->nativeformats;
01430    clone->rawreadformat = clone->nativeformats;
01431 }

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

Definition at line 1575 of file channel.c.

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

Referenced by ast_activate_generator(), and ast_read_generator_actions().

01576 {
01577    /* Called if generator doesn't have data */
01578    void *tmp;
01579    int res;
01580    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
01581    struct ast_channel *chan = (struct ast_channel *)data;
01582 
01583    ast_channel_lock(chan);
01584    tmp = chan->generatordata;
01585    chan->generatordata = NULL;
01586    if (chan->generator)
01587       generate = chan->generator->generate;
01588    ast_channel_unlock(chan);
01589 
01590    if (!tmp || !generate)
01591       return 0;
01592 
01593    res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50);
01594 
01595    chan->generatordata = tmp;
01596 
01597    if (res) {
01598       if (option_debug)
01599          ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
01600       ast_deactivate_generator(chan);
01601    }
01602 
01603    return 0;
01604 }

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

02794 {
02795    int native;
02796    int res;
02797    
02798    /* Make sure we only consider audio */
02799    fmt &= AST_FORMAT_AUDIO_MASK;
02800    
02801    native = chan->nativeformats;
02802    /* Find a translation path from the native format to one of the desired formats */
02803    if (!direction)
02804       /* reading */
02805       res = ast_translator_best_choice(&fmt, &native);
02806    else
02807       /* writing */
02808       res = ast_translator_best_choice(&native, &fmt);
02809 
02810    if (res < 0) {
02811       ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
02812          ast_getformatname(native), ast_getformatname(fmt));
02813       return -1;
02814    }
02815    
02816    /* Now we have a good choice for both. */
02817    ast_channel_lock(chan);
02818 
02819    if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
02820       /* the channel is already in these formats, so nothing to do */
02821       ast_channel_unlock(chan);
02822       return 0;
02823    }
02824 
02825    *rawformat = native;
02826    /* User perspective is fmt */
02827    *format = fmt;
02828    /* Free any read translation we have right now */
02829    if (*trans)
02830       ast_translator_free_path(*trans);
02831    /* Build a translation path from the raw format to the desired format */
02832    if (!direction)
02833       /* reading */
02834       *trans = ast_translator_build_path(*format, *rawformat);
02835    else
02836       /* writing */
02837       *trans = ast_translator_build_path(*rawformat, *format);
02838    ast_channel_unlock(chan);
02839    if (option_debug)
02840       ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name,
02841          direction ? "write" : "read", ast_getformatname(fmt));
02842    return 0;
02843 }

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

Definition at line 260 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.

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

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

Definition at line 207 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.

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

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

Definition at line 180 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.

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

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

Definition at line 4493 of file channel.c.

04494 {
04495    /* just store the data pointer in the channel structure */
04496    return data;
04497 }

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

Definition at line 4504 of file channel.c.

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

04505 {
04506    short buf[samples];
04507    struct ast_frame frame = {
04508       .frametype = AST_FRAME_VOICE,
04509       .subclass = AST_FORMAT_SLINEAR,
04510       .data = buf,
04511       .samples = samples,
04512       .datalen = sizeof(buf),
04513    };
04514    memset(buf, 0, sizeof(buf));
04515    if (ast_write(chan, &frame))
04516       return -1;
04517    return 0;
04518 }

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

Definition at line 4499 of file channel.c.

04500 {
04501    /* nothing to do */
04502 }

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

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

04258 {
04259    struct tonepair_state *ts;
04260    struct tonepair_def *td = params;
04261 
04262    if (!(ts = ast_calloc(1, sizeof(*ts))))
04263       return NULL;
04264    ts->origwfmt = chan->writeformat;
04265    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
04266       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
04267       tonepair_release(NULL, ts);
04268       ts = NULL;
04269    } else {
04270       ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
04271       ts->v1_1 = 0;
04272       ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
04273       ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
04274       ts->v2_1 = 0;
04275       ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
04276       ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
04277       ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
04278       ts->duration = td->duration;
04279       ts->modulate = 0;
04280    }
04281    /* Let interrupts interrupt :) */
04282    ast_set_flag(chan, AST_FLAG_WRITE_INT);
04283    return ts;
04284 }

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

Definition at line 4286 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.

04287 {
04288    struct tonepair_state *ts = data;
04289    int x;
04290 
04291    /* we need to prepare a frame with 16 * timelen samples as we're
04292     * generating SLIN audio
04293     */
04294    len = samples * 2;
04295 
04296    if (len > sizeof(ts->data) / 2 - 1) {
04297       ast_log(LOG_WARNING, "Can't generate that much data!\n");
04298       return -1;
04299    }
04300    memset(&ts->f, 0, sizeof(ts->f));
04301    for (x=0;x<len/2;x++) {
04302       ts->v1_1 = ts->v2_1;
04303       ts->v2_1 = ts->v3_1;
04304       ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
04305       
04306       ts->v1_2 = ts->v2_2;
04307       ts->v2_2 = ts->v3_2;
04308       ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
04309       if (ts->modulate) {
04310          int p;
04311          p = ts->v3_2 - 32768;
04312          if (p < 0) p = -p;
04313          p = ((p * 9) / 10) + 1;
04314          ts->data[x] = (ts->v3_1 * p) >> 15;
04315       } else
04316          ts->data[x] = ts->v3_1 + ts->v3_2; 
04317    }
04318    ts->f.frametype = AST_FRAME_VOICE;
04319    ts->f.subclass = AST_FORMAT_SLINEAR;
04320    ts->f.datalen = len;
04321    ts->f.samples = samples;
04322    ts->f.offset = AST_FRIENDLY_OFFSET;
04323    ts->f.data = ts->data;
04324    ast_write(chan, &ts->f);
04325    ts->pos += x;
04326    if (ts->duration > 0) {
04327       if (ts->pos >= ts->duration * 8)
04328          return -1;
04329    }
04330    return 0;
04331 }

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

Definition at line 4248 of file channel.c.

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

Referenced by tonepair_alloc().

04249 {
04250    struct tonepair_state *ts = params;
04251 
04252    if (chan)
04253       ast_set_write_format(chan, ts->origwfmt);
04254    free(ts);
04255 }


Variable Documentation

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

Definition at line 4409 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 4407 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 4408 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 375 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 370 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 365 of file channel.c.

unsigned long global_fin

Definition at line 84 of file channel.c.

unsigned long global_fout

Definition at line 84 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 704 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 361 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 357 of file channel.c.

int shutting_down [static]

Prevent new channel allocation if shutting down.

Definition at line 80 of file channel.c.

struct ast_generator silence_generator [static]

Initial value:

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

Referenced by ast_tonepair_start().

int uniqueint [static]

Definition at line 82 of file channel.c.


Generated on Mon Jul 14 17:25:15 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1