Codename Pineapple

Home page | Mailing list | Docs

Last updated: Sat Feb 3 05:01:24 2007

Asterisk developer's documentation :: Codename Pineapple


channel.c File Reference


Detailed Description

Channel Management.

Author:
Mark Spencer <markster@digium.com>

Definition in file channel.c.

#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/zapata.h"
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
#include "asterisk/sched.h"
#include "asterisk/options.h"
#include "asterisk/channel.h"
#include "asterisk/chanspy.h"
#include "asterisk/musiconhold.h"
#include "asterisk/logger.h"
#include "asterisk/say.h"
#include "asterisk/file.h"
#include "asterisk/cli.h"
#include "asterisk/translate.h"
#include "asterisk/manager.h"
#include "asterisk/chanvars.h"
#include "asterisk/linkedlists.h"
#include "asterisk/indications.h"
#include "asterisk/monitor.h"
#include "asterisk/causes.h"
#include "asterisk/callerid.h"
#include "asterisk/utils.h"
#include "asterisk/lock.h"
#include "asterisk/app.h"
#include "asterisk/transcap.h"
#include "asterisk/devicestate.h"
#include "asterisk/sha1.h"
#include "asterisk/threadstorage.h"
#include "asterisk/slinfactory.h"

Include dependency graph for channel.c:

Go to the source code of this file.

Data Structures

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

Defines

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

Enumerations

enum  spy_direction { SPY_READ, SPY_WRITE }

Functions

int __ast_answer (struct ast_channel *chan, unsigned int delay)
static struct ast_frame__ast_read (struct ast_channel *chan, int dropaudio)
ast_channel__ast_request_and_dial (const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
int ast_activate_generator (struct ast_channel *chan, struct ast_generator *gen, void *params)
int ast_active_channels (void)
 returns number of active/allocated channels
int ast_answer (struct ast_channel *chan)
 Answer a channel.
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 *name_fmt,...)
 Create a channel structure.
enum ast_bridge_result ast_channel_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc)
 Bridge two channels together.
int ast_channel_cmpwhentohangup (struct ast_channel *chan, time_t offset)
 Compare a offset with the settings of when to hang a channel up.
int ast_channel_datastore_add (struct ast_channel *chan, struct ast_datastore *datastore)
 Add a datastore to a channel.
ast_datastoreast_channel_datastore_alloc (const struct ast_datastore_info *info, char *uid)
 Create a channel datastore structure.
ast_datastoreast_channel_datastore_find (struct ast_channel *chan, const struct ast_datastore_info *info, char *uid)
 Find a datastore on a channel.
int ast_channel_datastore_free (struct ast_datastore *datastore)
 Free a channel datastore structure.
int ast_channel_datastore_remove (struct ast_channel *chan, struct ast_datastore *datastore)
 Remove a datastore from a channel.
int ast_channel_defer_dtmf (struct ast_channel *chan)
 Set defer DTMF flag on channel.
int ast_channel_early_bridge (struct ast_channel *c0, struct ast_channel *c1)
 Bridge two channels together (early).
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.
static int ast_channel_make_compatible_helper (struct ast_channel *from, struct ast_channel *to)
 Set up translation from one channel to another.
int ast_channel_masquerade (struct ast_channel *original, struct ast_channel *clone)
 Weird function made for call transfers.
int ast_channel_register (const struct ast_channel_tech *tech)
 Register a channel technology (a new channel driver) Called by a channel module to register the kind of channels it supports.
int ast_channel_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen)
int ast_channel_sendurl (struct ast_channel *chan, const char *url)
int ast_channel_setoption (struct ast_channel *chan, int option, void *data, int datalen, int block)
 Sets an option on a channel.
void ast_channel_setwhentohangup (struct ast_channel *chan, time_t offset)
 Set when to hang a channel up.
int ast_channel_spy_add (struct ast_channel *chan, struct ast_channel_spy *spy)
 Adds a spy to a channel, to begin receiving copies of the channel's audio frames.
void ast_channel_spy_free (struct ast_channel_spy *spy)
 Free a spy.
ast_frameast_channel_spy_read_frame (struct ast_channel_spy *spy, unsigned int samples)
 Read one (or more) frames of audio from a channel being spied upon.
void ast_channel_spy_remove (struct ast_channel *chan, struct ast_channel_spy *spy)
 Remove a spy from a channel.
void ast_channel_spy_stop_by_type (struct ast_channel *chan, const char *type)
 Find all spies of a particular type on a channel and stop them.
void ast_channel_spy_trigger_wait (struct ast_channel_spy *spy)
 Efficiently wait until audio is available for a spy, or an exception occurs.
ast_silence_generatorast_channel_start_silence_generator (struct ast_channel *chan)
 Starts a silence generator on the given channel.
void ast_channel_stop_silence_generator (struct ast_channel *chan, struct ast_silence_generator *state)
 Stops a previously-started silence generator on the given channel.
int ast_channel_supports_html (struct ast_channel *chan)
void ast_channel_undefer_dtmf (struct ast_channel *chan)
 Unset defer DTMF flag on channel.
void ast_channel_unregister (const struct ast_channel_tech *tech)
 Unregister a channel technology.
ast_channelast_channel_walk_locked (const struct ast_channel *prev)
 Browse channels in use Browse the channels currently in use.
int ast_channel_whisper_feed (struct ast_channel *chan, struct ast_frame *f)
 Feed an audio frame into the whisper buffer on a channel.
int ast_channel_whisper_start (struct ast_channel *chan)
 Begin 'whispering' onto a channel.
void ast_channel_whisper_stop (struct ast_channel *chan)
 Stop 'whispering' onto a channel.
void ast_channels_init (void)
ast_variableast_channeltype_list (void)
 return an ast_variable list of channeltypes
int ast_check_hangup (struct ast_channel *chan)
 Check to see if a channel is needing hang up.
static int ast_check_hangup_locked (struct ast_channel *chan)
void ast_deactivate_generator (struct ast_channel *chan)
int ast_do_masquerade (struct ast_channel *original)
 Start masquerading a channel XXX This is a seriously whacked 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).
const struct ast_channel_techast_get_channel_tech (const char *name)
 Get a channel technology structure by name.
ast_group_t ast_get_group (const char *s)
int ast_hangup (struct ast_channel *chan)
 Hang up a channel.
int ast_indicate (struct ast_channel *chan, int condition)
 Indicates condition of channel.
int ast_indicate_data (struct ast_channel *chan, int condition, const void *data, size_t datalen)
 Indicates condition of channel, with payload.
void ast_install_music_functions (int(*start_ptr)(struct ast_channel *, const char *, const char *), void(*stop_ptr)(struct ast_channel *), void(*cleanup_ptr)(struct ast_channel *))
int ast_internal_timing_enabled (struct ast_channel *chan)
 Check if the channel can run in internal timing mode.
static AST_LIST_HEAD_NOLOCK_STATIC (backends, chanlist)
static AST_LIST_HEAD_STATIC (channels, ast_channel)
void ast_moh_cleanup (struct ast_channel *chan)
int ast_moh_start (struct ast_channel *chan, const char *mclass, const char *interpclass)
 Turn on music on hold on a given channel.
void ast_moh_stop (struct ast_channel *chan)
 Turn off music on hold on a given channel.
char * ast_print_group (char *buf, int buflen, ast_group_t group)
 print call- and pickup groups into buffer
int ast_prod (struct ast_channel *chan)
 Send empty audio to prime a channel driver.
int ast_queue_control (struct ast_channel *chan, enum ast_control_frame_type control)
 Queue a control frame with payload.
int ast_queue_control_data (struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
 Queue a control frame with payload.
int ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin)
 Queue an outgoing frame.
int ast_queue_hangup (struct ast_channel *chan)
 Queue a hangup frame.
ast_frameast_read (struct ast_channel *chan)
 Reads a frame.
ast_frameast_read_noaudio (struct ast_channel *chan)
 Reads a frame, returning AST_FRAME_NULL frame if audio.
int ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
int ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
int ast_recvchar (struct ast_channel *chan, int timeout)
 Receives a text character from a channel.
char * ast_recvtext (struct ast_channel *chan, int timeout)
 Receives a text string from a channel Read a string of text from a channel.
ast_channelast_request (const char *type, int format, void *data, int *cause)
 Requests a channel.
ast_channelast_request_and_dial (const char *type, int format, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
 Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
int ast_safe_sleep (struct ast_channel *chan, int ms)
 Wait for a specified 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 specified amount of time, looking for hangups and a condition argument.
int ast_say_character_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang)
int ast_say_digit_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang)
int ast_say_digits (struct ast_channel *chan, int num, const char *ints, const char *lang)
int ast_say_digits_full (struct ast_channel *chan, int num, const char *ints, const char *lang, int audiofd, int ctrlfd)
int ast_say_enumeration (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options)
int ast_say_number (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options)
int ast_say_phonetic_str (struct ast_channel *chan, const char *str, const char *ints, const char *lang)
int ast_senddigit (struct ast_channel *chan, char digit)
 Send a DTMF digit to a channel Send a DTMF digit to a channel.
int ast_senddigit_begin (struct ast_channel *chan, char digit)
 Send a DTMF digit to a channel Send a DTMF digit to a channel.
int ast_senddigit_end (struct ast_channel *chan, char digit, unsigned int duration)
 Send a DTMF digit to a channel.
int ast_sendtext (struct ast_channel *chan, const char *text)
 Sends text to a channel Write text to a display on a channel.
void ast_set_callerid (struct ast_channel *chan, const char *callerid, const char *calleridname, const char *ani)
int ast_set_read_format (struct ast_channel *chan, int fmt)
 Sets read format on channel chan Set read format for channel to whichever component of "format" is best.
void ast_set_variables (struct ast_channel *chan, struct ast_variable *vars)
 adds a list of channel variables to a channel
int ast_set_write_format (struct ast_channel *chan, int fmt)
 Sets write format on channel chan Set write format for channel to whichever component of "format" is best.
int ast_setstate (struct ast_channel *chan, enum ast_channel_state state)
 Change the state of a channel.
int ast_settimeout (struct ast_channel *c, int samples, int(*func)(void *data), void *data)
int ast_shutting_down (void)
 Returns non-zero if Asterisk is being shut down.
int ast_softhangup (struct ast_channel *chan, int cause)
 Softly hangup up a channel.
int ast_softhangup_nolock (struct ast_channel *chan, int cause)
 Softly hangup up a channel (no channel lock).
const 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)
int ast_tonepair (struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
int ast_tonepair_start (struct ast_channel *chan, int freq1, int freq2, int duration, int vol)
void ast_tonepair_stop (struct ast_channel *chan)
int ast_transfer (struct ast_channel *chan, char *dest)
 Transfer a channel (if supported). Returns -1 on error, 0 if not supported and 1 if supported and requested.
char * ast_transfercapability2str (int transfercapability)
 Gives the string form of a given transfer capability.
void ast_uninstall_music_functions (void)
int ast_waitfor (struct ast_channel *c, int ms)
 Wait for input on a channel.
ast_channelast_waitfor_n (struct ast_channel **c, int n, int *ms)
 Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds.
int ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception)
 Waits for input on an fd This version works on fd's only. Be careful with it.
ast_channelast_waitfor_nandfds (struct ast_channel **c, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
 Waits for activity on a group of channels.
int ast_waitfordigit (struct ast_channel *c, int ms)
 Waits for a digit.
int ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int cmdfd)
 Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
ast_channelast_walk_channel_by_exten_locked (const struct ast_channel *chan, const char *exten, const char *context)
 Get next channel by exten (and optionally context) and lock it.
ast_channelast_walk_channel_by_name_prefix_locked (const struct ast_channel *chan, const char *name, const int namelen)
 Get channel by name prefix (locks channel).
int ast_write (struct ast_channel *chan, struct ast_frame *fr)
 Write a frame to a channel This function writes the given frame to the indicated channel.
int ast_write_video (struct ast_channel *chan, struct ast_frame *fr)
 Write video frame to a channel This function writes the given frame to the indicated channel.
static void bridge_playfile (struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
static struct ast_channelchannel_find_locked (const struct ast_channel *prev, const char *name, const int namelen, const char *context, const char *exten)
 Helper function to find channels.
const char * channelreloadreason2txt (enum channelreloadreason reason)
 Convert enum channelreloadreason to text string for manager event.
static void clone_variables (struct ast_channel *original, struct ast_channel *clone)
 Clone channel variables from 'clone' channel into 'original' channel.
static char * complete_channeltypes (const char *line, const char *word, int pos, int state)
static void copy_data_from_queue (struct ast_channel_spy_queue *queue, short *buf, unsigned int samples)
static void detach_spies (struct ast_channel *chan)
static void free_cid (struct ast_callerid *cid)
static void free_translation (struct ast_channel *clone)
static int generator_force (void *data)
static void queue_frame_to_spies (struct ast_channel *chan, struct ast_frame *f, enum spy_direction dir)
static int set_format (struct ast_channel *chan, int fmt, int *rawformat, int *format, struct ast_trans_pvt **trans, const int direction)
static int show_channeltype (int fd, int argc, char *argv[])
static int show_channeltypes (int fd, int argc, char *argv[])
static void * silence_generator_alloc (struct ast_channel *chan, void *data)
static int silence_generator_generate (struct ast_channel *chan, void *data, int len, int samples)
static void silence_generator_release (struct ast_channel *chan, void *data)
static void spy_cleanup (struct ast_channel *chan)
static void spy_detach (struct ast_channel_spy *spy, struct ast_channel *chan)
static void * tonepair_alloc (struct ast_channel *chan, void *params)
static int tonepair_generator (struct ast_channel *chan, void *data, int len, int samples)
static void tonepair_release (struct ast_channel *chan, void *params)

Variables

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


Define Documentation

#define AST_DEFAULT_EMULATE_DTMF_DURATION   100
 

100ms

Definition at line 105 of file channel.c.

Referenced by __ast_read().

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

#define SPY_QUEUE_SAMPLE_LIMIT   4000
 

Definition at line 1400 of file channel.c.

Referenced by queue_frame_to_spies().

#define STATE2STR_BUFSIZE   32
 

Definition at line 102 of file channel.c.

Referenced by ast_state2str().


Enumeration Type Documentation

enum spy_direction
 

Enumerator:
SPY_READ 
SPY_WRITE 

Definition at line 1395 of file channel.c.

01395                    {
01396    SPY_READ,
01397    SPY_WRITE,
01398 };


Function Documentation

int __ast_answer struct ast_channel chan,
unsigned int  delay
 

Definition at line 1612 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_safe_sleep(), ast_setstate(), AST_STATE_RING, AST_STATE_RINGING, AST_STATE_UP, ast_test_flag, ast_channel::cdr, and ast_channel::tech.

Referenced by ast_answer(), and pbx_builtin_answer().

01613 {
01614    int res = 0;
01615 
01616    ast_channel_lock(chan);
01617 
01618    /* You can't answer an outbound call */
01619    if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
01620       ast_channel_unlock(chan);
01621       return 0;
01622    }
01623 
01624    /* Stop if we're a zombie or need a soft hangup */
01625    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01626       ast_channel_unlock(chan);
01627       return -1;
01628    }
01629 
01630    switch (chan->_state) {
01631    case AST_STATE_RINGING:
01632    case AST_STATE_RING:
01633       if (chan->tech->answer)
01634          res = chan->tech->answer(chan);
01635       ast_setstate(chan, AST_STATE_UP);
01636       ast_cdr_answer(chan->cdr);
01637       ast_channel_unlock(chan);
01638       if (delay)
01639          ast_safe_sleep(chan, delay);
01640       return res;
01641       break;
01642    case AST_STATE_UP:
01643       ast_cdr_answer(chan->cdr);
01644       break;
01645    default:
01646       break;
01647    }
01648 
01649    ast_channel_unlock(chan);
01650 
01651    return res;
01652 }

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

Definition at line 1977 of file channel.c.

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

Referenced by ast_read(), and ast_read_noaudio().

01978 {
01979    struct ast_frame *f = NULL;   /* the return value */
01980    int blah;
01981    int prestate;
01982 
01983    /* this function is very long so make sure there is only one return
01984     * point at the end (there is only one exception to this).
01985     */
01986    ast_channel_lock(chan);
01987    if (chan->masq) {
01988       if (ast_do_masquerade(chan))
01989          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01990       else
01991          f =  &ast_null_frame;
01992       goto done;
01993    }
01994 
01995    /* Stop if we're a zombie or need a soft hangup */
01996    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01997       if (chan->generator)
01998          ast_deactivate_generator(chan);
01999       goto done;
02000    }
02001    prestate = chan->_state;
02002 
02003    if (!ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF | AST_FLAG_IN_DTMF) && 
02004        !ast_strlen_zero(chan->dtmfq)) {
02005       /* We have DTMF that has been deferred.  Return it now */
02006       chan->dtmff.subclass = chan->dtmfq[0];
02007       /* Drop first digit from the buffer */
02008       memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
02009       f = &chan->dtmff;
02010       if (ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY))
02011          chan->dtmff.frametype = AST_FRAME_DTMF_END;
02012       else {
02013          chan->dtmff.frametype = AST_FRAME_DTMF_BEGIN;
02014          ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02015          chan->emulate_dtmf_digit = f->subclass;
02016          chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
02017          chan->dtmf_begin_tv = ast_tvnow();
02018       }
02019       goto done;
02020    }
02021    
02022    /* Read and ignore anything on the alertpipe, but read only
02023       one sizeof(blah) per frame that we send from it */
02024    if (chan->alertpipe[0] > -1)
02025       read(chan->alertpipe[0], &blah, sizeof(blah));
02026 
02027 #ifdef HAVE_ZAPTEL
02028    if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02029       int res;
02030 
02031       ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02032       blah = -1;
02033       /* IF we can't get event, assume it's an expired as-per the old interface */
02034       res = ioctl(chan->timingfd, ZT_GETEVENT, &blah);
02035       if (res)
02036          blah = ZT_EVENT_TIMER_EXPIRED;
02037 
02038       if (blah == ZT_EVENT_TIMER_PING) {
02039          if (AST_LIST_EMPTY(&chan->readq) || !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
02040             /* Acknowledge PONG unless we need it again */
02041             if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) {
02042                ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
02043             }
02044          }
02045       } else if (blah == ZT_EVENT_TIMER_EXPIRED) {
02046          ioctl(chan->timingfd, ZT_TIMERACK, &blah);
02047          if (chan->timingfunc) {
02048             /* save a copy of func/data before unlocking the channel */
02049             int (*func)(void *) = chan->timingfunc;
02050             void *data = chan->timingdata;
02051             ast_channel_unlock(chan);
02052             func(data);
02053          } else {
02054             blah = 0;
02055             ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
02056             chan->timingdata = NULL;
02057             ast_channel_unlock(chan);
02058          }
02059          /* cannot 'goto done' because the channel is already unlocked */
02060          return &ast_null_frame;
02061       } else
02062          ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
02063    } else
02064 #endif
02065    if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
02066       /* if the AST_GENERATOR_FD is set, call the generator with args
02067        * set to -1 so it can do whatever it needs to.
02068        */
02069       void *tmp = chan->generatordata;
02070       chan->generatordata = NULL;     /* reset to let ast_write get through */
02071       chan->generator->generate(chan, tmp, -1, -1);
02072       chan->generatordata = tmp;
02073       f = &ast_null_frame;
02074       goto done;
02075    }
02076 
02077    /* Check for pending read queue */
02078    if (!AST_LIST_EMPTY(&chan->readq)) {
02079       f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list);
02080       /* Interpret hangup and return NULL */
02081       /* XXX why not the same for frames from the channel ? */
02082       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
02083          ast_frfree(f);
02084          f = NULL;
02085       }
02086    } else {
02087       chan->blocker = pthread_self();
02088       if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02089          if (chan->tech->exception)
02090             f = chan->tech->exception(chan);
02091          else {
02092             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
02093             f = &ast_null_frame;
02094          }
02095          /* Clear the exception flag */
02096          ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02097       } else if (chan->tech->read)
02098          f = chan->tech->read(chan);
02099       else
02100          ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
02101    }
02102 
02103    if (f) {
02104       /* if the channel driver returned more than one frame, stuff the excess
02105          into the readq for the next ast_read call (note that we can safely assume
02106          that the readq is empty, because otherwise we would not have called into
02107          the channel driver and f would be only a single frame)
02108       */
02109       if (AST_LIST_NEXT(f, frame_list)) {
02110          AST_LIST_HEAD_SET_NOLOCK(&chan->readq, AST_LIST_NEXT(f, frame_list));
02111          AST_LIST_NEXT(f, frame_list) = NULL;
02112       }
02113 
02114       switch (f->frametype) {
02115       case AST_FRAME_CONTROL:
02116          if (f->subclass == AST_CONTROL_ANSWER) {
02117             if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02118                if (option_debug)
02119                   ast_log(LOG_DEBUG, "Ignoring answer on an inbound call!\n");
02120                ast_frfree(f);
02121                f = &ast_null_frame;
02122             } else if (prestate == AST_STATE_UP) {
02123                if (option_debug)
02124                   ast_log(LOG_DEBUG, "Dropping duplicate answer!\n");
02125                ast_frfree(f);
02126                f = &ast_null_frame;
02127             } else {
02128                /* Answer the CDR */
02129                ast_setstate(chan, AST_STATE_UP);
02130                ast_cdr_answer(chan->cdr);
02131             }
02132          }
02133          break;
02134       case AST_FRAME_DTMF_END:
02135          ast_log(LOG_DTMF, "DTMF end '%c' received on %s\n", f->subclass, chan->name);
02136          /* Queue it up if DTMF is deffered, or if DTMF emulation is forced.
02137           * However, only let emulation be forced if the other end cares about BEGIN frames */
02138          if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF) ||
02139             (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) ) {
02140             if (strlen(chan->dtmfq) < sizeof(chan->dtmfq) - 2)
02141                chan->dtmfq[strlen(chan->dtmfq)] = f->subclass;
02142             else
02143                ast_log(LOG_WARNING, "Dropping deferred DTMF digits on %s\n", chan->name);
02144             ast_frfree(f);
02145             f = &ast_null_frame;
02146          } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
02147             f->frametype = AST_FRAME_DTMF_BEGIN;
02148             ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02149             chan->emulate_dtmf_digit = f->subclass;
02150             chan->dtmf_begin_tv = ast_tvnow();
02151             if (f->len)
02152                chan->emulate_dtmf_duration = f->len;
02153             else
02154                chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
02155          } else {
02156             ast_clear_flag(chan, AST_FLAG_IN_DTMF);
02157             if (!f->len)
02158                f->len = ast_tvdiff_ms(chan->dtmf_begin_tv, ast_tvnow());
02159          }
02160          break;
02161       case AST_FRAME_DTMF_BEGIN:
02162          ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name);
02163          if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY)) {
02164             ast_frfree(f);
02165             f = &ast_null_frame;
02166          } else {
02167             ast_set_flag(chan, AST_FLAG_IN_DTMF);
02168             chan->dtmf_begin_tv = ast_tvnow();
02169          }
02170          break;
02171       case AST_FRAME_VOICE:
02172          /* The EMULATE_DTMF flag must be cleared here as opposed to when the samples
02173           * first get to zero, because we want to make sure we pass at least one
02174           * voice frame through before starting the next digit, to ensure a gap
02175           * between DTMF digits. */
02176          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
02177             ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02178             chan->emulate_dtmf_digit = 0;
02179          }
02180 
02181          if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02182             ast_frfree(f);
02183             f = &ast_null_frame;
02184          } else if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
02185             if ((f->samples / 8) >= chan->emulate_dtmf_duration) { /* XXX 8kHz */
02186                chan->emulate_dtmf_duration = 0;
02187                f->frametype = AST_FRAME_DTMF_END;
02188                f->subclass = chan->emulate_dtmf_digit;
02189             } else {
02190                chan->emulate_dtmf_duration -= f->samples / 8; /* XXX 8kHz */
02191                ast_frfree(f);
02192                f = &ast_null_frame;
02193             }
02194          } else if (!(f->subclass & chan->nativeformats)) {
02195             /* This frame can't be from the current native formats -- drop it on the
02196                floor */
02197             ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
02198                chan->name, ast_getformatname(f->subclass), ast_getformatname(chan->nativeformats));
02199             ast_frfree(f);
02200             f = &ast_null_frame;
02201          } else {
02202             if (chan->spies)
02203                queue_frame_to_spies(chan, f, SPY_READ);
02204             
02205             if (chan->monitor && chan->monitor->read_stream ) {
02206                /* XXX what does this do ? */
02207 #ifndef MONITOR_CONSTANT_DELAY
02208                int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
02209                if (jump >= 0) {
02210                   jump = chan->outsmpl - chan->insmpl;
02211                   if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
02212                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
02213                   chan->insmpl += jump + f->samples;
02214                } else
02215                   chan->insmpl+= f->samples;
02216 #else
02217                int jump = chan->outsmpl - chan->insmpl;
02218                if (jump - MONITOR_DELAY >= 0) {
02219                   if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
02220                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
02221                   chan->insmpl += jump;
02222                } else
02223                   chan->insmpl += f->samples;
02224 #endif
02225                if (chan->monitor->state == AST_MONITOR_RUNNING) {
02226                   if (ast_writestream(chan->monitor->read_stream, f) < 0)
02227                      ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
02228                }
02229             }
02230 
02231             if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL)
02232                f = &ast_null_frame;
02233 
02234             /* Run generator sitting on the line if timing device not available
02235             * and synchronous generation of outgoing frames is necessary       */
02236             if (chan->generatordata &&  !ast_internal_timing_enabled(chan)) {
02237                void *tmp = chan->generatordata;
02238                int res;
02239 
02240                if (chan->timingfunc) {
02241                   if (option_debug > 1)
02242                      ast_log(LOG_DEBUG, "Generator got voice, switching to phase locked mode\n");
02243                   ast_settimeout(chan, 0, NULL, NULL);
02244                }
02245 
02246                chan->generatordata = NULL;   /* reset, to let writes go through */
02247                res = chan->generator->generate(chan, tmp, f->datalen, f->samples);
02248                chan->generatordata = tmp;
02249                if (res) {
02250                   if (option_debug > 1)
02251                      ast_log(LOG_DEBUG, "Auto-deactivating generator\n");
02252                   ast_deactivate_generator(chan);
02253                }
02254 
02255             } else if (f->frametype == AST_FRAME_CNG) {
02256                if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
02257                   if (option_debug > 1)
02258                      ast_log(LOG_DEBUG, "Generator got CNG, switching to timed mode\n");
02259                   ast_settimeout(chan, 160, generator_force, chan);
02260                }
02261             }
02262          }
02263       default:
02264          /* Just pass it on! */
02265          break;
02266       }
02267    } else {
02268       /* Make sure we always return NULL in the future */
02269       chan->_softhangup |= AST_SOFTHANGUP_DEV;
02270       if (chan->generator)
02271          ast_deactivate_generator(chan);
02272       /* End the CDR if appropriate */
02273       if (chan->cdr)
02274          ast_cdr_end(chan->cdr);
02275    }
02276 
02277    /* High bit prints debugging */
02278    if (chan->fin & DEBUGCHAN_FLAG)
02279       ast_frame_dump(chan->name, f, "<<");
02280    chan->fin = FRAMECOUNT_INC(chan->fin);
02281 
02282 done:
02283    ast_channel_unlock(chan);
02284    return f;
02285 }

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

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

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

02773 {
02774    int dummy_outstate;
02775    int cause = 0;
02776    struct ast_channel *chan;
02777    int res = 0;
02778    
02779    if (outstate)
02780       *outstate = 0;
02781    else
02782       outstate = &dummy_outstate;   /* make outstate always a valid pointer */
02783 
02784    chan = ast_request(type, format, data, &cause);
02785    if (!chan) {
02786       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
02787       /* compute error and return */
02788       if (cause == AST_CAUSE_BUSY)
02789          *outstate = AST_CONTROL_BUSY;
02790       else if (cause == AST_CAUSE_CONGESTION)
02791          *outstate = AST_CONTROL_CONGESTION;
02792       return NULL;
02793    }
02794 
02795    if (oh) {
02796       if (oh->vars)  
02797          ast_set_variables(chan, oh->vars);
02798       /* XXX why is this necessary, for the parent_channel perhaps ? */
02799       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
02800          ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
02801       if (oh->parent_channel)
02802          ast_channel_inherit_variables(oh->parent_channel, chan);
02803       if (oh->account)
02804          ast_cdr_setaccount(chan, oh->account); 
02805    }
02806    ast_set_callerid(chan, cid_num, cid_name, cid_num);
02807 
02808    if (ast_call(chan, data, 0)) {   /* ast_call failed... */
02809       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
02810    } else {
02811       res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
02812       while (timeout && chan->_state != AST_STATE_UP) {
02813          struct ast_frame *f;
02814          res = ast_waitfor(chan, timeout);
02815          if (res <= 0) /* error, timeout, or done */
02816             break;
02817          if (timeout > -1)
02818             timeout = res;
02819          f = ast_read(chan);
02820          if (!f) {
02821             *outstate = AST_CONTROL_HANGUP;
02822             res = 0;
02823             break;
02824          }
02825          if (f->frametype == AST_FRAME_CONTROL) {
02826             switch (f->subclass) {
02827             case AST_CONTROL_RINGING:  /* record but keep going */
02828                *outstate = f->subclass;
02829                break;
02830 
02831             case AST_CONTROL_BUSY:
02832             case AST_CONTROL_CONGESTION:
02833             case AST_CONTROL_ANSWER:
02834                *outstate = f->subclass;
02835                timeout = 0;      /* trick to force exit from the while() */
02836                break;
02837 
02838             /* Ignore these */
02839             case AST_CONTROL_PROGRESS:
02840             case AST_CONTROL_PROCEEDING:
02841             case AST_CONTROL_HOLD:
02842             case AST_CONTROL_UNHOLD:
02843             case AST_CONTROL_VIDUPDATE:
02844             case -1:       /* Ignore -- just stopping indications */
02845                break;
02846 
02847             default:
02848                ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
02849             }
02850          }
02851          ast_frfree(f);
02852       }
02853    }
02854 
02855    /* Final fixups */
02856    if (oh) {
02857       if (!ast_strlen_zero(oh->context))
02858          ast_copy_string(chan->context, oh->context, sizeof(chan->context));
02859       if (!ast_strlen_zero(oh->exten))
02860          ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
02861       if (oh->priority) 
02862          chan->priority = oh->priority;
02863    }
02864    if (chan->_state == AST_STATE_UP)
02865       *outstate = AST_CONTROL_ANSWER;
02866 
02867    if (res <= 0) {
02868       if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
02869          ast_cdr_init(chan->cdr, chan);
02870       if (chan->cdr) {
02871          char tmp[256];
02872          snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
02873          ast_cdr_setapp(chan->cdr,"Dial",tmp);
02874          ast_cdr_update(chan);
02875          ast_cdr_start(chan->cdr);
02876          ast_cdr_end(chan->cdr);
02877          /* If the cause wasn't handled properly */
02878          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
02879             ast_cdr_failed(chan->cdr);
02880       }
02881       ast_hangup(chan);
02882       chan = NULL;
02883    }
02884    return chan;
02885 }

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

Activate a given generator

Definition at line 1694 of file channel.c.

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

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

01695 {
01696    int res = 0;
01697 
01698    ast_channel_lock(chan);
01699 
01700    if (chan->generatordata) {
01701       if (chan->generator && chan->generator->release)
01702          chan->generator->release(chan, chan->generatordata);
01703       chan->generatordata = NULL;
01704    }
01705 
01706    ast_prod(chan);
01707    if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
01708       res = -1;
01709    }
01710    
01711    if (!res) {
01712       ast_settimeout(chan, 160, generator_force, chan);
01713       chan->generator = gen;
01714    }
01715 
01716    ast_channel_unlock(chan);
01717 
01718    return res;
01719 }

int ast_active_channels void   ) 
 

returns number of active/allocated channels

Returns number of active/allocated channels

Definition at line 345 of file channel.c.

References AST_LIST_LOCK, AST_LIST_TRAVERSE, and AST_LIST_UNLOCK.

Referenced by quit_handler().

00346 {
00347    struct ast_channel *c;
00348    int cnt = 0;
00349    AST_LIST_LOCK(&channels);
00350    AST_LIST_TRAVERSE(&channels, c, chan_list)
00351       cnt++;
00352    AST_LIST_UNLOCK(&channels);
00353    return cnt;
00354 }

int ast_answer struct ast_channel chan  ) 
 

Answer a channel.

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

Definition at line 1654 of file channel.c.

References __ast_answer().

Referenced by __login_exec(), agi_exec_full(), ast_bridge_call(), ast_control_streamfile(), ast_pickup_call(), builtin_parkcall(), features_answer(), handle_answer(), park_call_exec(), park_exec(), and pbx_builtin_background().

01655 {
01656    return __ast_answer(chan, 500);
01657 }

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

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

Referenced by quit_handler().

00333 {
00334    struct ast_channel *c;
00335    shutting_down = 1;
00336    if (hangup) {
00337       AST_LIST_LOCK(&channels);
00338       AST_LIST_TRAVERSE(&channels, c, chan_list)
00339          ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00340       AST_LIST_UNLOCK(&channels);
00341    }
00342 }

int ast_best_codec int  fmts  ) 
 

Pick the best audio 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

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

References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_AUDIO_MASK, 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_iax2_new(), builtin_atxfer(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), jingle_new(), local_new(), mgcp_new(), sip_new(), skinny_new(), socket_process(), and transmit_connect().

00560 {
00561    /* This just our opinion, expressed in code.  We are asked to choose
00562       the best codec to use, given no information */
00563    int x;
00564    static int prefs[] =
00565    {
00566       /*! Okay, ulaw is used by all telephony equipment, so start with it */
00567       AST_FORMAT_ULAW,
00568       /*! Unless of course, you're a silly European, so then prefer ALAW */
00569       AST_FORMAT_ALAW,
00570       /*! Okay, well, signed linear is easy to translate into other stuff */
00571       AST_FORMAT_SLINEAR,
00572       /*! G.726 is standard ADPCM, in RFC3551 packing order */
00573       AST_FORMAT_G726,
00574       /*! G.726 is standard ADPCM, in AAL2 packing order */
00575       AST_FORMAT_G726_AAL2,
00576       /*! ADPCM has great sound quality and is still pretty easy to translate */
00577       AST_FORMAT_ADPCM,
00578       /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to
00579           translate and sounds pretty good */
00580       AST_FORMAT_GSM,
00581       /*! iLBC is not too bad */
00582       AST_FORMAT_ILBC,
00583       /*! Speex is free, but computationally more expensive than GSM */
00584       AST_FORMAT_SPEEX,
00585       /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
00586           to use it */
00587       AST_FORMAT_LPC10,
00588       /*! G.729a is faster than 723 and slightly less expensive */
00589       AST_FORMAT_G729A,
00590       /*! Down to G.723.1 which is proprietary but at least designed for voice */
00591       AST_FORMAT_G723_1,
00592    };
00593 
00594    /* Strip out video */
00595    fmts &= AST_FORMAT_AUDIO_MASK;
00596    
00597    /* Find the first preferred codec in the format given */
00598    for (x=0; x < (sizeof(prefs) / sizeof(prefs[0]) ); x++)
00599       if (fmts & prefs[x])
00600          return prefs[x];
00601    ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
00602    return 0;
00603 }

struct ast_channel* ast_bridged_channel struct ast_channel chan  ) 
 

Find bridged channel.

Parameters:
chan Current channel

Definition at line 3589 of file channel.c.

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

Referenced by __zt_exception(), agents_show(), agents_show_online(), ast_channel_masquerade(), attempt_transfer(), console_transfer(), create_jb(), handle_chanlist(), handle_hd_hf(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_invite(), handle_request_refer(), handle_response_answer(), handle_response_invite(), handle_showchan(), local_attended_transfer(), mgcp_hangup(), mgcp_ss(), schedule_delivery(), sip_read(), socket_process(), ss_thread(), zt_handle_event(), and zt_hangup().

03590 {
03591    struct ast_channel *bridged;
03592    bridged = chan->_bridge;
03593    if (bridged && bridged->tech->bridged_channel)
03594       bridged = bridged->tech->bridged_channel(chan, bridged);
03595    return bridged;
03596 }

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

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

Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), begin_dial(), and features_call().

02942 {
02943    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
02944       If the remote end does not answer within the timeout, then do NOT hang up, but
02945       return anyway.  */
02946    int res = -1;
02947    /* Stop if we're a zombie or need a soft hangup */
02948    ast_channel_lock(chan);
02949    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
02950       if (chan->tech->call)
02951          res = chan->tech->call(chan, addr, timeout);
02952       ast_set_flag(chan, AST_FLAG_OUTGOING);
02953    }
02954    ast_channel_unlock(chan);
02955    return res;
02956 }

void ast_cancel_shutdown void   ) 
 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 357 of file channel.c.

References shutting_down.

Referenced by handle_abort_halt().

00358 {
00359    shutting_down = 0;
00360 }

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

References causes, and desc.

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

00478 {
00479    int x;
00480 
00481    for (x=0; x < sizeof(causes) / sizeof(causes[0]); x++) {
00482       if (causes[x].cause == cause)
00483          return causes[x].desc;
00484    }
00485 
00486    return "Unknown";
00487 }

void ast_change_name struct ast_channel chan,
char *  newname
 

Change channel name.

Definition at line 3162 of file channel.c.

References ast_string_field_set, EVENT_FLAG_CALL, manager_event, and name.

03163 {
03164    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
03165    ast_string_field_set(chan, name, newname);
03166 }

struct ast_channel* ast_channel_alloc int  needalertpipe,
int  state,
const char *  cid_num,
const char *  cid_name,
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 611 of file channel.c.

References ast_calloc, ast_log(), AST_MAX_FDS, ast_string_field_init, free, LOG_WARNING, sched_context_create(), and shutting_down.

Referenced by __oh323_new(), agent_new(), alsa_new(), ast_async_goto(), ast_iax2_new(), ast_masq_park_call(), ast_pbx_outgoing_cdr_failed(), ast_pbx_outgoing_exten(), builtin_atxfer(), check_goto_on_transfer(), gtalk_new(), iax_park(), jingle_new(), local_new(), mgcp_new(), nbs_new(), oss_new(), phone_new(), sip_new(), sip_park(), and skinny_new().

00612 {
00613    struct ast_channel *tmp;
00614    int x;
00615    int flags;
00616    struct varshead *headp;
00617    va_list ap1, ap2;
00618 
00619    /* If shutting down, don't allocate any new channels */
00620    if (shutting_down) {
00621       ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
00622       return NULL;
00623    }
00624 
00625    if (!(tmp = ast_calloc(1, sizeof(*tmp))))
00626       return NULL;
00627 
00628    if (!(tmp->sched = sched_context_create())) {
00629       ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
00630       free(tmp);
00631       return NULL;
00632    }
00633    
00634    ast_string_field_init(tmp, 128);
00635 
00636    /* Don't bother initializing the last two FD here, because they
00637       will *always* be set just a few lines down (AST_TIMING_FD,
00638       AST_ALERT_FD). */
00639    for (x = 0; x < AST_MAX_FDS - 2; x++)
00640       tmp->fds[x] = -1;
00641 
00642 #ifdef HAVE_ZAPTEL
00643    tmp->timingfd = open("/dev/zap/timer", O_RDWR);
00644    if (tmp->timingfd > -1) {
00645       /* Check if timing interface supports new
00646          ping/pong scheme */
00647       flags = 1;
00648       if (!ioctl(tmp->timingfd, ZT_TIMERPONG, &flags))
00649          needqueue = 0;
00650    }
00651 #else
00652    tmp->timingfd = -1;              
00653 #endif               
00654 
00655    if (needqueue) {
00656       if (pipe(tmp->alertpipe)) {
00657          ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe!\n");
00658          ast_string_field_free_pools(tmp);
00659          free(tmp);
00660          return NULL;
00661       } else {
00662          flags = fcntl(tmp->alertpipe[0], F_GETFL);
00663          fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK);
00664          flags = fcntl(tmp->alertpipe[1], F_GETFL);
00665          fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK);
00666       }
00667    } else   /* Make sure we've got it done right if they don't */
00668       tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
00669 
00670    /* Always watch the alertpipe */
00671    tmp->fds[AST_ALERT_FD] = tmp->alertpipe[0];
00672    /* And timing pipe */
00673    tmp->fds[AST_TIMING_FD] = tmp->timingfd;
00674    ast_string_field_set(tmp, name, "**Unknown**");
00675 
00676    /* Initial state */
00677    tmp->_state = state;
00678 
00679    tmp->streamid = -1;
00680    
00681    tmp->fin = global_fin;
00682    tmp->fout = global_fout;
00683 
00684    if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
00685       ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL), 
00686                    ast_atomic_fetchadd_int(&uniqueint, 1));
00687    } else {
00688       ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, 
00689                    (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
00690    }
00691 
00692    if (!ast_strlen_zero(name_fmt)) {
00693       /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call.
00694        * And they all use slightly different formats for their name string.
00695        * This means, to set the name here, we have to accept variable args, and call the string_field_build from here.
00696        * This means, that the stringfields must have a routine that takes the va_lists directly, and 
00697        * uses them to build the string, instead of forming the va_lists internally from the vararg ... list.
00698        * This new function was written so this can be accomplished.
00699        */
00700       va_start(ap1, name_fmt);
00701       va_start(ap2, name_fmt);
00702       ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2);
00703       va_end(ap1);
00704       va_end(ap2);
00705 
00706       /* and now, since the channel structure is built, and has its name, let's call the
00707        * manager event generator with this Newchannel event. This is the proper and correct
00708        * place to make this call, but you sure do have to pass a lot of data into this func
00709        * to do it here!
00710        */
00711       manager_event(EVENT_FLAG_CALL, "Newchannel",
00712                "Channel: %s\r\n"
00713                "State: %s\r\n"
00714                "CallerIDNum: %s\r\n"
00715                "CallerIDName: %s\r\n"
00716                "Uniqueid: %s\r\n",
00717                tmp->name, ast_state2str(state),
00718                S_OR(cid_num, "<unknown>"),
00719                S_OR(cid_name, "<unknown>"),
00720                tmp->uniqueid);
00721    }
00722    
00723    headp = &tmp->varshead;
00724    AST_LIST_HEAD_INIT_NOLOCK(headp);
00725    
00726    ast_mutex_init(&tmp->lock);
00727    
00728    AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
00729    
00730    strcpy(tmp->context, "default");
00731    strcpy(tmp->exten, "s");
00732    tmp->priority = 1;
00733    
00734    ast_string_field_set(tmp, language, defaultlanguage);
00735    tmp->amaflags = ast_default_amaflags;
00736    ast_string_field_set(tmp, accountcode, ast_default_accountcode);
00737 
00738    tmp->tech = &null_tech;
00739 
00740    AST_LIST_LOCK(&channels);
00741    AST_LIST_INSERT_HEAD(&channels, tmp, chan_list);
00742    AST_LIST_UNLOCK(&channels);
00743 
00744    return tmp;
00745 }

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

References ast_channel::_bridge, AST_BRIDGE_COMPLETE, ast_check_hangup_locked(), AST_FEATURE_PLAY_WARNING, AST_FLAG_END_DTMF_ONLY, AST_FLAG_ZOMBIE, ast_log(), ast_set_flag, ast_test_flag, ast_tvadd(), ast_tvsub(), bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, config, EVENT_FLAG_CALL, LOG_WARNING, manager_event, ast_channel::nativeformats, ast_channel_tech::send_digit_begin, and ast_channel::tech.

Referenced by ast_bridge_call().

03790 {
03791    struct ast_channel *who = NULL;
03792    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
03793    int nativefailed=0;
03794    int firstpass;
03795    int o0nativeformats;
03796    int o1nativeformats;
03797    long time_left_ms=0;
03798    struct timeval nexteventts = { 0, };
03799    char caller_warning = 0;
03800    char callee_warning = 0;
03801 
03802    if (c0->_bridge) {
03803       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
03804          c0->name, c0->_bridge->name);
03805       return -1;
03806    }
03807    if (c1->_bridge) {
03808       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
03809          c1->name, c1->_bridge->name);
03810       return -1;
03811    }
03812    
03813    /* Stop if we're a zombie or need a soft hangup */
03814    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
03815        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
03816       return -1;
03817 
03818    *fo = NULL;
03819    firstpass = config->firstpass;
03820    config->firstpass = 0;
03821 
03822    if (ast_tvzero(config->start_time))
03823       config->start_time = ast_tvnow();
03824    time_left_ms = config->timelimit;
03825 
03826    caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
03827    callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
03828 
03829    if (config->start_sound && firstpass) {
03830       if (caller_warning)
03831          bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000);
03832       if (callee_warning)
03833          bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000);
03834    }
03835 
03836    /* Keep track of bridge */
03837    c0->_bridge = c1;
03838    c1->_bridge = c0;
03839 
03840    /* \todo  XXX here should check that cid_num is not NULL */
03841    manager_event(EVENT_FLAG_CALL, "Link",
03842             "Channel1: %s\r\n"
03843             "Channel2: %s\r\n"
03844             "Uniqueid1: %s\r\n"
03845             "Uniqueid2: %s\r\n"
03846             "CallerID1: %s\r\n"
03847             "CallerID2: %s\r\n",
03848             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03849 
03850    o0nativeformats = c0->nativeformats;
03851    o1nativeformats = c1->nativeformats;
03852 
03853    if (config->feature_timer) {
03854       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
03855    } else if (config->timelimit) {
03856       nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
03857       if (caller_warning || callee_warning)
03858          nexteventts = ast_tvsub(nexteventts, ast_samp2tv(config->play_warning, 1000));
03859    }
03860 
03861    if (!c0->tech->send_digit_begin)
03862       ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
03863    if (!c1->tech->send_digit_begin)
03864       ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
03865 
03866    for (/* ever */;;) {
03867       struct timeval now = { 0, };
03868       int to;
03869 
03870       to = -1;
03871 
03872       if (!ast_tvzero(nexteventts)) {
03873          now = ast_tvnow();
03874          to = ast_tvdiff_ms(nexteventts, now);
03875          if (to <= 0) {
03876             if (!config->timelimit) {
03877                res = AST_BRIDGE_COMPLETE;
03878                break;
03879             }
03880             to = 0;
03881          }
03882       }
03883 
03884       if (config->timelimit) {
03885          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
03886          if (time_left_ms < to)
03887             to = time_left_ms;
03888 
03889          if (time_left_ms <= 0) {
03890             if (caller_warning && config->end_sound)
03891                bridge_playfile(c0, c1, config->end_sound, 0);
03892             if (callee_warning && config->end_sound)
03893                bridge_playfile(c1, c0, config->end_sound, 0);
03894             *fo = NULL;
03895             if (who)
03896                *rc = who;
03897             res = 0;
03898             break;
03899          }
03900          
03901          if (!to) {
03902             if (time_left_ms >= 5000 && config->warning_sound && config->play_warning) {
03903                int t = (time_left_ms + 500) / 1000; /* round to nearest second */
03904                if (caller_warning)
03905                   bridge_playfile(c0, c1, config->warning_sound, t);
03906                if (callee_warning)
03907                   bridge_playfile(c1, c0, config->warning_sound, t);
03908             }
03909             if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000)))
03910                nexteventts = ast_tvadd(nexteventts, ast_samp2tv(config->warning_freq, 1000));
03911             else
03912                nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
03913          }
03914       }
03915 
03916       if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
03917          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03918             c0->_softhangup = 0;
03919          if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03920             c1->_softhangup = 0;
03921          c0->_bridge = c1;
03922          c1->_bridge = c0;
03923          if (option_debug)
03924             ast_log(LOG_DEBUG, "Unbridge signal received. Ending native bridge.\n");
03925          continue;
03926       }
03927       
03928       /* Stop if we're a zombie or need a soft hangup */
03929       if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
03930           ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
03931          *fo = NULL;
03932          if (who)
03933             *rc = who;
03934          res = 0;
03935          if (option_debug)
03936             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",
03937                c0->name, c1->name,
03938                ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
03939                ast_check_hangup(c0) ? "Yes" : "No",
03940                ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
03941                ast_check_hangup(c1) ? "Yes" : "No");
03942          break;
03943       }
03944 
03945       if (c0->tech->bridge &&
03946           (config->timelimit == 0) &&
03947           (c0->tech->bridge == c1->tech->bridge) &&
03948           !nativefailed && !c0->monitor && !c1->monitor &&
03949           !c0->spies && !c1->spies && !ast_test_flag(&(config->features_callee),AST_FEATURE_REDIRECT) &&
03950           !ast_test_flag(&(config->features_caller),AST_FEATURE_REDIRECT) ) {
03951          /* Looks like they share a bridge method and nothing else is in the way */
03952          ast_set_flag(c0, AST_FLAG_NBRIDGE);
03953          ast_set_flag(c1, AST_FLAG_NBRIDGE);
03954          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
03955             /* \todo  XXX here should check that cid_num is not NULL */
03956             manager_event(EVENT_FLAG_CALL, "Unlink",
03957                      "Channel1: %s\r\n"
03958                      "Channel2: %s\r\n"
03959                      "Uniqueid1: %s\r\n"
03960                      "Uniqueid2: %s\r\n"
03961                      "CallerID1: %s\r\n"
03962                      "CallerID2: %s\r\n",
03963                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
03964             if (option_debug)
03965                ast_log(LOG_DEBUG, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
03966 
03967             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
03968             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
03969 
03970             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
03971                continue;
03972 
03973             c0->_bridge = NULL;
03974             c1->_bridge = NULL;
03975 
03976             return res;
03977          } else {
03978             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
03979             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
03980          }
03981          switch (res) {
03982          case AST_BRIDGE_RETRY:
03983             continue;
03984          default:
03985             if (option_verbose > 2)
03986                ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s ended\n",
03987                       c0->name, c1->name);
03988             /* fallthrough */
03989          case AST_BRIDGE_FAILED_NOWARN:
03990             nativefailed++;
03991             break;
03992          }
03993       }
03994    
03995       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
03996           (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
03997           !(c0->generator || c1->generator)) {
03998          if (ast_channel_make_compatible(c0, c1)) {
03999             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
04000             /* \todo  XXX here should check that cid_num is not NULL */
04001                                 manager_event(EVENT_FLAG_CALL, "Unlink",
04002                      "Channel1: %s\r\n"
04003                      "Channel2: %s\r\n"
04004                      "Uniqueid1: %s\r\n"
04005                      "Uniqueid2: %s\r\n"
04006                      "CallerID1: %s\r\n"
04007                      "CallerID2: %s\r\n",
04008                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04009             return AST_BRIDGE_FAILED;
04010          }
04011          o0nativeformats = c0->nativeformats;
04012          o1nativeformats = c1->nativeformats;
04013       }
04014       res = ast_generic_bridge(c0, c1, config, fo, rc, nexteventts);
04015       if (res != AST_BRIDGE_RETRY)
04016          break;
04017    }
04018 
04019    ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
04020    ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
04021 
04022    c0->_bridge = NULL;
04023    c1->_bridge = NULL;
04024 
04025    /* \todo  XXX here should check that cid_num is not NULL */
04026    manager_event(EVENT_FLAG_CALL, "Unlink",
04027             "Channel1: %s\r\n"
04028             "Channel2: %s\r\n"
04029             "Uniqueid1: %s\r\n"
04030             "Uniqueid2: %s\r\n"
04031             "CallerID1: %s\r\n"
04032             "CallerID2: %s\r\n",
04033             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
04034    if (option_debug)
04035       ast_log(LOG_DEBUG, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
04036 
04037    return res;
04038 }

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 return -1.

Definition at line 377 of file channel.c.

References ast_channel::whentohangup.

00378 {
00379    time_t whentohangup;
00380 
00381    if (chan->whentohangup == 0) {
00382       return (offset == 0) ? 0 : -1;
00383    } else {
00384       if (offset == 0)  /* XXX why is this special ? */
00385          return (1);
00386       else {
00387          whentohangup = offset + time (NULL);
00388          if (chan->whentohangup < whentohangup)
00389             return (1);
00390          else if (chan->whentohangup == whentohangup)
00391             return (0);
00392          else
00393             return (-1);
00394       }
00395    }
00396 }

int ast_channel_datastore_add struct ast_channel chan,
struct ast_datastore datastore
 

Add a datastore to a channel.

Definition at line 1142 of file channel.c.

References AST_LIST_INSERT_HEAD.

01143 {
01144    int res = 0;
01145 
01146    AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
01147 
01148    return res;
01149 }

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

Create a channel datastore structure.

Definition at line 1098 of file channel.c.

References ast_calloc, ast_strdup, and ast_datastore::info.

01099 {
01100    struct ast_datastore *datastore = NULL;
01101 
01102    /* Make sure we at least have type so we can identify this */
01103    if (info == NULL) {
01104       return NULL;
01105    }
01106 
01107    /* Allocate memory for datastore and clear it */
01108    datastore = ast_calloc(1, sizeof(*datastore));
01109    if (datastore == NULL) {
01110       return NULL;
01111    }
01112 
01113    datastore->info = info;
01114 
01115    datastore->uid = ast_strdup(uid);
01116 
01117    return datastore;
01118 }

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

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

01170 {
01171    struct ast_datastore *datastore = NULL;
01172    
01173    if (info == NULL)
01174       return NULL;
01175 
01176    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
01177       if (datastore->info == info) {
01178          if (uid != NULL && datastore->uid != NULL) {
01179             if (!strcasecmp(uid, datastore->uid)) {
01180                /* Matched by type AND uid */
01181                break;
01182             }
01183          } else {
01184             /* Matched by type at least */
01185             break;
01186          }
01187       }
01188    }
01189    AST_LIST_TRAVERSE_SAFE_END
01190 
01191    return datastore;
01192 }

int ast_channel_datastore_free struct ast_datastore datastore  ) 
 

Free a channel datastore structure.

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

01121 {
01122    int res = 0;
01123 
01124    /* Using the destroy function (if present) destroy the data */
01125    if (datastore->info->destroy != NULL && datastore->data != NULL) {
01126       datastore->info->destroy(datastore->data);
01127       datastore->data = NULL;
01128    }
01129 
01130    /* Free allocated UID memory */
01131    if (datastore->uid != NULL) {
01132       free(datastore->uid);
01133       datastore->uid = NULL;
01134    }
01135 
01136    /* Finally free memory used by ourselves */
01137    free(datastore);
01138 
01139    return res;
01140 }

int ast_channel_datastore_remove struct ast_channel chan,
struct ast_datastore datastore
 

Remove a datastore from a channel.

Definition at line 1151 of file channel.c.

References AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, and AST_LIST_TRAVERSE_SAFE_END.

01152 {
01153    struct ast_datastore *datastore2 = NULL;
01154    int res = -1;
01155 
01156    /* Find our position and remove ourselves */
01157    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore2, entry) {
01158       if (datastore2 == datastore) {
01159          AST_LIST_REMOVE_CURRENT(&chan->datastores, entry);
01160          res = 0;
01161          break;
01162       }
01163    }
01164    AST_LIST_TRAVERSE_SAFE_END
01165 
01166    return res;
01167 }

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

References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.

Referenced by find_cache().

00840 {
00841    int pre = 0;
00842 
00843    if (chan) {
00844       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
00845       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
00846    }
00847    return pre;
00848 }

int ast_channel_early_bridge struct ast_channel c0,
struct ast_channel c1
 

Bridge two channels together (early).

Bridge two channels together (early)

Parameters:
c0 first channel to bridge
c1 second channel to bridge Bridge two channels (c0 and c1) together early. This implies either side may not be answered yet.
Returns:
Returns 0 on success and -1 if it could not be done

Definition at line 3778 of file channel.c.

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

03779 {
03780    /* Make sure we can early bridge, if not error out */
03781    if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge)))
03782       return -1;
03783 
03784    return c0->tech->early_bridge(c0, c1);
03785 }

void ast_channel_free struct ast_channel chan  ) 
 

Free a channel structure.

Definition at line 1018 of file channel.c.

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

Referenced by agent_cleanup(), agent_new(), ast_hangup(), ast_pbx_outgoing_cdr_failed(), and local_new().

01019 {
01020    int fd;
01021    struct ast_var_t *vardata;
01022    struct ast_frame *f;
01023    struct varshead *headp;
01024    struct ast_datastore *datastore = NULL;
01025    char name[AST_CHANNEL_NAME];
01026    
01027    headp=&chan->varshead;
01028    
01029    AST_LIST_LOCK(&channels);
01030    AST_LIST_REMOVE(&channels, chan, chan_list);
01031    /* Lock and unlock the channel just to be sure nobody
01032       has it locked still */
01033    ast_channel_lock(chan);
01034    ast_channel_unlock(chan);
01035    if (chan->tech_pvt) {
01036       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
01037       free(chan->tech_pvt);
01038    }
01039 
01040    if (chan->sched)
01041       sched_context_destroy(chan->sched);
01042 
01043    ast_copy_string(name, chan->name, sizeof(name));
01044 
01045    /* Stop monitoring */
01046    if (chan->monitor)
01047       chan->monitor->stop( chan, 0 );
01048 
01049    /* If there is native format music-on-hold state, free it */
01050    if (chan->music_state)
01051       ast_moh_cleanup(chan);
01052 
01053    /* if someone is whispering on the channel, stop them */
01054    if (chan->whisper)
01055       ast_channel_whisper_stop(chan);
01056 
01057    /* Free translators */
01058    if (chan->readtrans)
01059       ast_translator_free_path(chan->readtrans);
01060    if (chan->writetrans)
01061       ast_translator_free_path(chan->writetrans);
01062    if (chan->pbx)
01063       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
01064    free_cid(&chan->cid);
01065    ast_mutex_destroy(&chan->lock);
01066    /* Close pipes if appropriate */
01067    if ((fd = chan->alertpipe[0]) > -1)
01068       close(fd);
01069    if ((fd = chan->alertpipe[1]) > -1)
01070       close(fd);
01071    if ((fd = chan->timingfd) > -1)
01072       close(fd);
01073    while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
01074       ast_frfree(f);
01075    
01076    /* Get rid of each of the data stores on the channel */
01077    while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
01078       /* Free the data store */
01079       ast_channel_datastore_free(datastore);
01080    AST_LIST_HEAD_INIT_NOLOCK(&chan->datastores);
01081 
01082    /* loop over the variables list, freeing all data and deleting list items */
01083    /* no need to lock the list, as the channel is already locked */
01084    
01085    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
01086       ast_var_delete(vardata);
01087 
01088    /* Destroy the jitterbuffer */
01089    ast_jb_destroy(chan);
01090 
01091    ast_string_field_free_pools(chan);
01092    free(chan);
01093    AST_LIST_UNLOCK(&channels);
01094 
01095    ast_device_state_changed_literal(name);
01096 }

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

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

Referenced by __ast_request_and_dial(), agent_call(), ast_feature_request_and_dial(), and begin_dial().

03169 {
03170    struct ast_var_t *current, *newvar;
03171    const char *varname;
03172 
03173    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
03174       int vartype = 0;
03175 
03176       varname = ast_var_full_name(current);
03177       if (!varname)
03178          continue;
03179 
03180       if (varname[0] == '_') {
03181          vartype = 1;
03182          if (varname[1] == '_')
03183             vartype = 2;
03184       }
03185 
03186       switch (vartype) {
03187       case 1:
03188          newvar = ast_var_assign(&varname[1], ast_var_value(current));
03189          if (newvar) {
03190             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03191             if (option_debug)
03192                ast_log(LOG_DEBUG, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
03193          }
03194          break;
03195       case 2:
03196          newvar = ast_var_assign(ast_var_full_name(current), ast_var_value(current));
03197          if (newvar) {
03198             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
03199             if (option_debug)
03200                ast_log(LOG_DEBUG, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
03201          }
03202          break;
03203       default:
03204          if (option_debug)
03205             ast_log(LOG_DEBUG, "Not copying variable %s.\n", ast_var_name(current));
03206          break;
03207       }
03208    }
03209 }

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

References ast_channel_make_compatible_helper().

Referenced by check_compat(), and park_exec().

03081 {
03082    /* Some callers do not check return code, and we must try to set all call legs correctly */
03083    int rc = 0;
03084 
03085    /* Set up translation from the chan to the peer */
03086    rc = ast_channel_make_compatible_helper(chan, peer);
03087 
03088    if (rc < 0)
03089       return rc;
03090 
03091    /* Set up translation from the peer to the chan */
03092    rc = ast_channel_make_compatible_helper(peer, chan);
03093 
03094    return rc;
03095 }

static int ast_channel_make_compatible_helper struct ast_channel from,
struct ast_channel to
[static]
 

Set up translation from one channel to another.

Definition at line 3049 of file channel.c.

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

Referenced by ast_channel_make_compatible().

03050 {
03051    int src;
03052    int dst;
03053 
03054    /* Set up translation from the 'from' channel to the 'to' channel */
03055    src = from->nativeformats;
03056    dst = to->nativeformats;
03057    if (ast_translator_best_choice(&dst, &src) < 0) {
03058       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", from->name, src, to->name, dst);
03059       return -1;
03060    }
03061 
03062    /* if the best path is not 'pass through', then
03063       transcoding is needed; if desired, force transcode path
03064       to use SLINEAR between channels, but only if there is
03065       no direct conversion available */
03066    if ((src != dst) && ast_opt_transcode_via_slin &&
03067        (ast_translate_path_steps(dst, src) != 1))
03068       dst = AST_FORMAT_SLINEAR;
03069    if (ast_set_read_format(from, dst) < 0) {
03070       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", from->name, dst);
03071       return -1;
03072    }
03073    if (ast_set_write_format(to, dst) < 0) {
03074       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", to->name, dst);
03075       return -1;
03076    }
03077    return 0;
03078 }

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

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

Referenced by ast_async_goto(), ast_masq_park_call(), ast_pickup_call(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), handle_invite_replaces(), iax_park(), misdn_transfer_bc(), and sip_park().

03098 {
03099    int res = -1;
03100    struct ast_channel *final_orig = original, *final_clone = clone;
03101 
03102    ast_channel_lock(original);
03103    while (ast_channel_trylock(clone)) {
03104       ast_channel_unlock(original);
03105       usleep(1);
03106       ast_channel_lock(original);
03107    }
03108 
03109    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
03110       and if so, we don't really want to masquerade it, but its proxy */
03111    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)))
03112       final_orig = original->_bridge;
03113 
03114    if (clone->_bridge && (clone->_bridge != ast_bridged_channel(clone)))
03115       final_clone = clone->_bridge;
03116 
03117    if ((final_orig != original) || (final_clone != clone)) {
03118       ast_channel_lock(final_orig);
03119       while (ast_channel_trylock(final_clone)) {
03120          ast_channel_unlock(final_orig);
03121          usleep(1);
03122          ast_channel_lock(final_orig);
03123       }
03124       ast_channel_unlock(clone);
03125       ast_channel_unlock(original);
03126       original = final_orig;
03127       clone = final_clone;
03128    }
03129 
03130    if (original == clone) {
03131       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
03132       ast_channel_unlock(clone);
03133       ast_channel_unlock(original);
03134       return -1;
03135    }
03136 
03137    if (option_debug)
03138       ast_log(LOG_DEBUG, "Planning to masquerade channel %s into the structure of %s\n",
03139          clone->name, original->name);
03140    if (original->masq) {
03141       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03142          original->masq->name, original->name);
03143    } else if (clone->masqr) {
03144       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
03145          clone->name, clone->masqr->name);
03146    } else {
03147       original->masq = clone;
03148       clone->masqr = original;
03149       ast_queue_frame(original, &ast_null_frame);
03150       ast_queue_frame(clone, &ast_null_frame);
03151       if (option_debug)
03152          ast_log(LOG_DEBUG, "Done planning to masquerade channel %s into the structure of %s\n", clone->name, original->name);
03153       res = 0;
03154    }
03155 
03156    ast_channel_unlock(clone);
03157    ast_channel_unlock(original);
03158 
03159    return res;
03160 }

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

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

Referenced by load_module(), and unload_module().

00400 {
00401    struct chanlist *chan;
00402 
00403    AST_LIST_LOCK(&channels);
00404 
00405    AST_LIST_TRAVERSE(&backends, chan, list) {
00406       if (!strcasecmp(tech->type, chan->tech->type)) {
00407          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00408          AST_LIST_UNLOCK(&channels);
00409          return -1;
00410       }
00411    }
00412    
00413    if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00414       AST_LIST_UNLOCK(&channels);
00415       return -1;
00416    }
00417    chan->tech = tech;
00418    AST_LIST_INSERT_HEAD(&backends, chan, list);
00419 
00420    if (option_debug)
00421       ast_log(LOG_DEBUG, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00422 
00423    if (option_verbose > 1)
00424       ast_verbose(VERBOSE_PREFIX_2 "Registered channel type '%s' (%s)\n", chan->tech->type,
00425              chan->tech->description);
00426 
00427    AST_LIST_UNLOCK(&channels);
00428    return 0;
00429 }

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

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

Referenced by agent_sendhtml(), and ast_channel_sendurl().

03037 {
03038    if (chan->tech->send_html)
03039       return chan->tech->send_html(chan, subclass, data, datalen);
03040    return -1;
03041 }

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

References ast_channel_sendhtml(), and AST_HTML_URL.

03044 {
03045    return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
03046 }

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

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

Referenced by ast_bridge_call(), handle_tddmode(), and zt_hangup().

04042 {
04043    int res;
04044 
04045    if (chan->tech->setoption) {
04046       res = chan->tech->setoption(chan, option, data, datalen);
04047       if (res < 0)
04048          return res;
04049    } else {
04050       errno = ENOSYS;
04051       return -1;
04052    }
04053    if (block) {
04054       /* XXX Implement blocking -- just wait for our option frame reply, discarding
04055          intermediate packets. XXX */
04056       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
04057       return -1;
04058    }
04059    return 0;
04060 }

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

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

Referenced by action_timeout().

00370 {
00371    chan->whentohangup = offset ? time(NULL) + offset : 0;
00372    ast_queue_frame(chan, &ast_null_frame);
00373    return;
00374 }

int ast_channel_spy_add struct ast_channel chan,
struct ast_channel_spy spy
 

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

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

Definition at line 1194 of file channel.c.

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

01195 {
01196    /* Link the owner channel to the spy */
01197    spy->chan = chan;
01198 
01199    if (!ast_test_flag(spy, CHANSPY_FORMAT_AUDIO)) {
01200       ast_log(LOG_WARNING, "Could not add channel spy '%s' to channel '%s', only audio format spies are supported.\n",
01201          spy->type, chan->name);
01202       return -1;
01203    }
01204 
01205    if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST) && (spy->read_queue.format != AST_FORMAT_SLINEAR)) {
01206       ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n",
01207          ast_getformatname(spy->read_queue.format));
01208       return -1;
01209    }
01210 
01211    if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST) && (spy->write_queue.format != AST_FORMAT_SLINEAR)) {
01212       ast_log(LOG_WARNING, "Cannot provide volume adjustment on '%s' format spies\n",
01213          ast_getformatname(spy->write_queue.format));
01214       return -1;
01215    }
01216 
01217    if (ast_test_flag(spy, CHANSPY_MIXAUDIO) &&
01218        ((spy->read_queue.format != AST_FORMAT_SLINEAR) ||
01219         (spy->write_queue.format != AST_FORMAT_SLINEAR))) {
01220       ast_log(LOG_WARNING, "Cannot provide audio mixing on '%s'-'%s' format spies\n",
01221          ast_getformatname(spy->read_queue.format), ast_getformatname(spy->write_queue.format));
01222       return -1;
01223    }
01224 
01225    if (!chan->spies) {
01226       if (!(chan->spies = ast_calloc(1, sizeof(*chan->spies)))) {
01227          return -1;
01228       }
01229 
01230       AST_LIST_HEAD_INIT_NOLOCK(&chan->spies->list);
01231       AST_LIST_INSERT_HEAD(&chan->spies->list, spy, list);
01232    } else {
01233       AST_LIST_INSERT_TAIL(&chan->spies->list, spy, list);
01234    }
01235 
01236    if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE) {
01237       ast_cond_init(&spy->trigger, NULL);
01238       ast_set_flag(spy, CHANSPY_TRIGGER_READ);
01239       ast_clear_flag(spy, CHANSPY_TRIGGER_WRITE);
01240    }
01241 
01242    if (option_debug)
01243       ast_log(LOG_DEBUG, "Spy %s added to channel %s\n",
01244          spy->type, chan->name);
01245 
01246    return 0;
01247 }

void ast_channel_spy_free struct ast_channel_spy spy  ) 
 

Free a spy.

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

Definition at line 1329 of file channel.c.

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

01330 {
01331    struct ast_frame *f = NULL;
01332 
01333    if (spy->status == CHANSPY_DONE)
01334       return;
01335 
01336    /* Switch status to done in case we get called twice */
01337    spy->status = CHANSPY_DONE;
01338 
01339    /* Drop any frames in the queue */
01340    while ((f = AST_LIST_REMOVE_HEAD(&spy->write_queue.list, frame_list)))
01341       ast_frfree(f);
01342    while ((f = AST_LIST_REMOVE_HEAD(&spy->read_queue.list, frame_list)))
01343       ast_frfree(f);
01344 
01345    /* Destroy the condition if in use */
01346    if (ast_test_flag(spy, CHANSPY_TRIGGER_MODE) != CHANSPY_TRIGGER_NONE)
01347       ast_cond_destroy(&spy->trigger);
01348 
01349    /* Destroy our mutex since it is no longer in use */
01350    ast_mutex_destroy(&spy->lock);
01351 
01352    return;
01353 }

struct ast_frame* ast_channel_spy_read_frame struct ast_channel_spy spy,
unsigned int  samples
 

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

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

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

Definition at line 4357 of file channel.c.

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

04358 {
04359    struct ast_frame *result;
04360    /* buffers are allocated to hold SLINEAR, which is the largest format */
04361         short read_buf[samples];
04362         short write_buf[samples];
04363    struct ast_frame *read_frame;
04364    struct ast_frame *write_frame;
04365    int need_dup;
04366    struct ast_frame stack_read_frame = { .frametype = AST_FRAME_VOICE,
04367                      .subclass = spy->read_queue.format,
04368                      .data = read_buf,
04369                      .samples = samples,
04370                      .datalen = ast_codec_get_len(spy->read_queue.format, samples),
04371    };
04372    struct ast_frame stack_write_frame = { .frametype = AST_FRAME_VOICE,
04373                       .subclass = spy->write_queue.format,
04374                       .data = write_buf,
04375                       .samples = samples,
04376                       .datalen = ast_codec_get_len(spy->write_queue.format, samples),
04377    };
04378 
04379    /* if a flush has been requested, dump everything in whichever queue is larger */
04380    if (ast_test_flag(spy, CHANSPY_TRIGGER_FLUSH)) {
04381       if (spy->read_queue.samples > spy->write_queue.samples) {
04382          if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST)) {
04383             AST_LIST_TRAVERSE(&spy->read_queue.list, result, frame_list)
04384                ast_frame_adjust_volume(result, spy->read_vol_adjustment);
04385          }
04386          result = AST_LIST_FIRST(&spy->read_queue.list);
04387          AST_LIST_HEAD_SET_NOLOCK(&spy->read_queue.list, NULL);
04388          spy->read_queue.samples = 0;
04389       } else {
04390          if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST)) {
04391             AST_LIST_TRAVERSE(&spy->write_queue.list, result, frame_list)
04392                ast_frame_adjust_volume(result, spy->write_vol_adjustment);
04393          }
04394          result = AST_LIST_FIRST(&spy->write_queue.list);
04395          AST_LIST_HEAD_SET_NOLOCK(&spy->write_queue.list, NULL);
04396          spy->write_queue.samples = 0;
04397       }
04398       ast_clear_flag(spy, CHANSPY_TRIGGER_FLUSH);
04399       return result;
04400    }
04401 
04402    if ((spy->read_queue.samples < samples) || (spy->write_queue.samples < samples))
04403       return NULL;
04404 
04405    /* short-circuit if both head frames have exactly what we want */
04406    if ((AST_LIST_FIRST(&spy->read_queue.list)->samples == samples) &&
04407        (AST_LIST_FIRST(&spy->write_queue.list)->samples == samples)) {
04408       read_frame = AST_LIST_REMOVE_HEAD(&spy->read_queue.list, frame_list);
04409       write_frame = AST_LIST_REMOVE_HEAD(&spy->write_queue.list, frame_list);
04410 
04411       spy->read_queue.samples -= samples;
04412       spy->write_queue.samples -= samples;
04413 
04414       need_dup = 0;
04415    } else {
04416       copy_data_from_queue(&spy->read_queue, read_buf, samples);
04417       copy_data_from_queue(&spy->write_queue, write_buf, samples);
04418 
04419       read_frame = &stack_read_frame;
04420       write_frame = &stack_write_frame;
04421       need_dup = 1;
04422    }
04423    
04424    if (ast_test_flag(spy, CHANSPY_READ_VOLADJUST))
04425       ast_frame_adjust_volume(read_frame, spy->read_vol_adjustment);
04426 
04427    if (ast_test_flag(spy, CHANSPY_WRITE_VOLADJUST))
04428       ast_frame_adjust_volume(write_frame, spy->write_vol_adjustment);
04429 
04430    if (ast_test_flag(spy, CHANSPY_MIXAUDIO)) {
04431       ast_frame_slinear_sum(read_frame, write_frame);
04432 
04433       if (need_dup)
04434          result = ast_frdup(read_frame);
04435       else {
04436          result = read_frame;
04437          ast_frfree(write_frame);
04438       }
04439    } else {
04440       if (need_dup) {
04441          result = ast_frdup(read_frame);
04442          AST_LIST_NEXT(result, frame_list) = ast_frdup(write_frame);
04443       } else {
04444          result = read_frame;
04445          AST_LIST_NEXT(result, frame_list) = write_frame;
04446       }
04447    }
04448 
04449    return result;
04450 }

void ast_channel_spy_remove struct ast_channel chan,
struct ast_channel_spy spy
 

Remove a spy from a channel.

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

Definition at line 1319 of file channel.c.

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

01320 {
01321    if (!chan->spies)
01322       return;
01323 
01324    AST_LIST_REMOVE(&chan->spies->list, spy, list);
01325    spy_detach(spy, chan);
01326    spy_cleanup(chan);
01327 }

void ast_channel_spy_stop_by_type struct ast_channel chan,
const char *  type
 

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

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

Definition at line 1287 of file channel.c.

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

01288 {
01289    struct ast_channel_spy *spy = NULL;
01290    
01291    if (!chan->spies)
01292       return;
01293 
01294    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->spies->list, spy, list) {
01295       ast_mutex_lock(&spy->lock);
01296       if ((spy->type == type) && (spy->status == CHANSPY_RUNNING)) {
01297          ast_mutex_unlock(&spy->lock);
01298          AST_LIST_REMOVE_CURRENT(&chan->spies->list, list);
01299          spy_detach(spy, chan);
01300       } else
01301          ast_mutex_unlock(&spy->lock);
01302    }
01303    AST_LIST_TRAVERSE_SAFE_END
01304    spy_cleanup(chan);
01305 }

void ast_channel_spy_trigger_wait struct ast_channel_spy spy  ) 
 

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

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

Definition at line 1307 of file channel.c.

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

01308 {
01309    struct timeval tv;
01310    struct timespec ts;
01311 
01312    tv = ast_tvadd(ast_tvnow(), ast_samp2tv(50000, 1000));
01313    ts.tv_sec = tv.tv_sec;
01314    ts.tv_nsec = tv.tv_usec * 1000;
01315 
01316    ast_cond_timedwait(&spy->trigger, &spy->lock, &ts);
01317 }

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

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

04490 {
04491    struct ast_silence_generator *state;
04492 
04493    if (!(state = ast_calloc(1, sizeof(*state)))) {
04494       return NULL;
04495    }
04496 
04497    state->old_write_format = chan->writeformat;
04498 
04499    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
04500       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
04501       free(state);
04502       return NULL;
04503    }
04504 
04505    ast_activate_generator(chan, &silence_generator, state);
04506 
04507    if (option_debug)
04508       ast_log(LOG_DEBUG, "Started silence generator on '%s'\n", chan->name);
04509 
04510    return state;
04511 }

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

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

04514 {
04515    if (!state)
04516       return;
04517 
04518    ast_deactivate_generator(chan);
04519 
04520    if (option_debug)
04521       ast_log(LOG_DEBUG, "Stopped silence generator on '%s'\n", chan->name);
04522 
04523    if (ast_set_write_format(chan, state->old_write_format) < 0)
04524       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
04525 
04526    free(state);
04527 }

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

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

03032 {
03033    return (chan->tech->send_html) ? 1 : 0;
03034 }

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

References ast_clear_flag, and AST_FLAG_DEFER_DTMF.

Referenced by find_cache().

00852 {
00853    if (chan)
00854       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
00855 }

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

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

Referenced by __unload_module(), and unload_module().

00432 {
00433    struct chanlist *chan;
00434 
00435    if (option_debug)
00436       ast_log(LOG_DEBUG, "Unregistering channel type '%s'\n", tech->type);
00437 
00438    AST_LIST_LOCK(&channels);
00439 
00440    AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00441       if (chan->tech == tech) {
00442          AST_LIST_REMOVE_CURRENT(&backends, list);
00443          free(chan);
00444          if (option_verbose > 1)
00445             ast_verbose(VERBOSE_PREFIX_2 "Unregistered channel type '%s'\n", tech->type);
00446          break;   
00447       }
00448    }
00449    AST_LIST_TRAVERSE_SAFE_END
00450 
00451    AST_LIST_UNLOCK(&channels);
00452 }

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

References channel_find_locked().

Referenced by action_status(), ast_app_group_get_count(), ast_app_group_match_get_count(), ast_complete_channels(), ast_pickup_call(), complete_ch_helper(), group_show_channels(), handle_chanlist(), handle_core_set_debug_channel(), and moh_on_off().

00939 {
00940    return channel_find_locked(prev, NULL, 0, NULL, NULL);
00941 }

int ast_channel_whisper_feed struct ast_channel chan,
struct ast_frame f
 

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

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

Definition at line 4732 of file channel.c.

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

04733 {
04734    if (!chan->whisper)
04735       return -1;
04736 
04737    ast_mutex_lock(&chan->whisper->lock);
04738    ast_slinfactory_feed(&chan->whisper->sf, f);
04739    ast_mutex_unlock(&chan->whisper->lock);
04740 
04741    return 0;
04742 }

int ast_channel_whisper_start struct ast_channel chan  ) 
 

Begin 'whispering' onto a channel.

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

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

Definition at line 4717 of file channel.c.

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

04718 {
04719    if (chan->whisper)
04720       return -1;
04721 
04722    if (!(chan->whisper = ast_calloc(1, sizeof(*chan->whisper))))
04723       return -1;
04724 
04725    ast_mutex_init(&chan->whisper->lock);
04726    ast_slinfactory_init(&chan->whisper->sf);
04727    ast_set_flag(chan, AST_FLAG_WHISPER);
04728 
04729    return 0;
04730 }

void ast_channel_whisper_stop struct ast_channel chan  ) 
 

Stop 'whispering' onto a channel.

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

Definition at line 4744 of file channel.c.

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

Referenced by ast_channel_free().

04745 {
04746    if (!chan->whisper)
04747       return;
04748 
04749    ast_clear_flag(chan, AST_FLAG_WHISPER);
04750    if (chan->whisper->path)
04751       ast_translator_free_path(chan->whisper->path);
04752    if (chan->whisper->original_format && chan->writeformat == AST_FORMAT_SLINEAR)
04753       ast_set_write_format(chan, chan->whisper->original_format);
04754    ast_slinfactory_destroy(&chan->whisper->sf);
04755    ast_mutex_destroy(&chan->whisper->lock);
04756    free(chan->whisper);
04757    chan->whisper = NULL;
04758 }

void ast_channels_init void   ) 
 

Provided by channel.c

Definition at line 4290 of file channel.c.

References ast_cli_register_multiple(), and cli_channel.

04291 {
04292    ast_cli_register_multiple(cli_channel, sizeof(cli_channel) / sizeof(struct ast_cli_entry));
04293 }

struct ast_variable* ast_channeltype_list void   ) 
 

return an ast_variable list of channeltypes

Definition at line 171 of file channel.c.

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

00172 {
00173    struct chanlist *cl;
00174    struct ast_variable *var=NULL, *prev = NULL;
00175    AST_LIST_TRAVERSE(&backends, cl, list) {
00176       if (prev)  {
00177          if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description)))
00178             prev = prev->next;
00179       } else {
00180          var = ast_variable_new(cl->tech->type, cl->tech->description);
00181          prev = var;
00182       }
00183    }
00184    return var;
00185 }

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

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

Referenced by __ast_answer(), __ast_read(), ast_call(), ast_check_hangup_locked(), ast_feature_request_and_dial(), ast_indicate_data(), ast_readstring_full(), ast_recvtext(), ast_sendtext(), ast_transfer(), ast_waitfordigit_full(), ast_write(), builtin_atxfer(), handle_sendimage(), and zt_setoption().

00309 {
00310    if (chan->_softhangup)     /* yes if soft hangup flag set */
00311       return 1;
00312    if (!chan->tech_pvt)    /* yes if no technology private data */
00313       return 1;
00314    if (!chan->whentohangup)   /* no if no hangup scheduled */
00315       return 0;
00316    if (chan->whentohangup > time(NULL))   /* no if hangup time has not come yet. */
00317       return 0;
00318    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */
00319    return 1;
00320 }

static int ast_check_hangup_locked struct ast_channel chan  )  [static]
 

Definition at line 322 of file channel.c.

References ast_channel_lock, ast_channel_unlock, and ast_check_hangup().

Referenced by ast_channel_bridge().

00323 {
00324    int res;
00325    ast_channel_lock(chan);
00326    res = ast_check_hangup(chan);
00327    ast_channel_unlock(chan);
00328    return res;
00329 }

void ast_deactivate_generator struct ast_channel chan  ) 
 

Deactivate an active generator

Definition at line 1659 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(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_playtones_stop(), ast_quiet_chan(), ast_tonepair_stop(), ast_write(), generator_force(), local_ast_moh_stop(), and moh_on_off().

01660 {
01661    ast_channel_lock(chan);
01662    if (chan->generatordata) {
01663       if (chan->generator && chan->generator->release)
01664          chan->generator->release(chan, chan->generatordata);
01665       chan->generatordata = NULL;
01666       chan->generator = NULL;
01667       chan->fds[AST_GENERATOR_FD] = -1;
01668       ast_clear_flag(chan, AST_FLAG_WRITE_INT);
01669       ast_settimeout(chan, 0, NULL, NULL);
01670    }
01671    ast_channel_unlock(chan);
01672 }

int ast_do_masquerade struct ast_channel original  ) 
 

Start masquerading a channel XXX This is a seriously whacked 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 3249 of file channel.c.

References ast_channel::_state, ast_channel::alertpipe, ast_channel_lock, AST_LIST_FIRST, AST_LIST_HEAD_SET_NOLOCK, ast_log(), ast_state2str(), ast_string_field_set, EVENT_FLAG_CALL, free_translation(), ast_channel::lock, LOG_DEBUG, manager_event, ast_channel::masq, ast_channel::masqr, name, option_debug, ast_channel::readformat, ast_channel::tech, ast_channel::tech_pvt, and ast_channel::writeformat.

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

03250 {
03251    int x,i;
03252    int res=0;
03253    int origstate;
03254    struct ast_frame *cur;
03255    const struct ast_channel_tech *t;
03256    void *t_pvt;
03257    struct ast_callerid tmpcid;
03258    struct ast_channel *clone = original->masq;
03259    struct ast_channel_spy_list *spy_list = NULL;
03260    struct ast_channel_spy *spy = NULL;
03261    int rformat = original->readformat;
03262    int wformat = original->writeformat;
03263    char newn[100];
03264    char orig[100];
03265    char masqn[100];
03266    char zombn[100];
03267 
03268    if (option_debug > 3)
03269       ast_log(LOG_DEBUG, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
03270          clone->name, clone->_state, original->name, original->_state);
03271 
03272    manager_event(EVENT_FLAG_CALL, "Masquerade", "Clone: %s\r\nCloneState: %s\r\nOriginal: %s\r\nOriginalState: %s\r\n",
03273             clone->name, ast_state2str(clone->_state), original->name, ast_state2str(original->_state));
03274 
03275    /* XXX This is a seriously wacked out operation.  We're essentially putting the guts of
03276       the clone channel into the original channel.  Start by killing off the original
03277       channel's backend.   I'm not sure we're going to keep this function, because
03278       while the features are nice, the cost is very high in terms of pure nastiness. XXX */
03279 
03280    /* We need the clone's lock, too */
03281    ast_channel_lock(clone);
03282 
03283    if (option_debug > 1)
03284       ast_log(LOG_DEBUG, "Got clone lock for masquerade on '%s' at %p\n", clone->name, &clone->lock);
03285 
03286    /* Having remembered the original read/write formats, we turn off any translation on either
03287       one */
03288    free_translation(clone);
03289    free_translation(original);
03290 
03291 
03292    /* Unlink the masquerade */
03293    original->masq = NULL;
03294    clone->masqr = NULL;
03295    
03296    /* Save the original name */
03297    ast_copy_string(orig, original->name, sizeof(orig));
03298    /* Save the new name */
03299    ast_copy_string(newn, clone->name, sizeof(newn));
03300    /* Create the masq name */
03301    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
03302       
03303    /* Copy the name from the clone channel */
03304    ast_string_field_set(original, name, newn);
03305 
03306    /* Mangle the name of the clone channel */
03307    ast_string_field_set(clone, name, masqn);
03308    
03309    /* Notify any managers of the change, first the masq then the other */
03310    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clone->uniqueid);
03311    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
03312 
03313    /* Swap the technologies */   
03314    t = original->tech;
03315    original->tech = clone->tech;
03316    clone->tech = t;
03317 
03318    t_pvt = original->tech_pvt;
03319    original->tech_pvt = clone->tech_pvt;
03320    clone->tech_pvt = t_pvt;
03321 
03322    /* Swap the readq's */
03323    cur = AST_LIST_FIRST(&original->readq);
03324    AST_LIST_HEAD_SET_NOLOCK(&original->readq, AST_LIST_FIRST(&clone->readq));
03325    AST_LIST_HEAD_SET_NOLOCK(&clone->readq, cur);
03326 
03327    /* Swap the alertpipes */
03328    for (i = 0; i < 2; i++) {
03329       x = original->alertpipe[i];
03330       original->alertpipe[i] = clone->alertpipe[i];
03331       clone->alertpipe[i] = x;
03332    }
03333 
03334    /* Swap the raw formats */
03335    x = original->rawreadformat;
03336    original->rawreadformat = clone->rawreadformat;
03337    clone->rawreadformat = x;
03338    x = original->rawwriteformat;
03339    original->rawwriteformat = clone->rawwriteformat;
03340    clone->rawwriteformat = x;
03341 
03342    /* Swap the spies */
03343    spy_list = original->spies;
03344    original->spies = clone->spies;
03345    clone->spies = spy_list;
03346 
03347    /* Update channel on respective spy lists if present */
03348    if (original->spies) {
03349       AST_LIST_TRAVERSE(&original->spies->list, spy, list) {
03350          ast_mutex_lock(&spy->lock);
03351          spy->chan = original;
03352          ast_mutex_unlock(&spy->lock);
03353       }
03354    }
03355    if (clone->spies) {
03356       AST_LIST_TRAVERSE(&clone->spies->list, spy, list) {
03357          ast_mutex_lock(&spy->lock);
03358          spy->chan = clone;
03359          ast_mutex_unlock(&spy->lock);
03360       }
03361    }
03362 
03363    /* Save any pending frames on both sides.  Start by counting
03364     * how many we're going to need... */
03365    x = 0;
03366    if (original->alertpipe[1] > -1) {
03367       AST_LIST_TRAVERSE(&clone->readq, cur, frame_list)
03368          x++;
03369    }
03370 
03371    /* If we had any, prepend them to the ones already in the queue, and 
03372     * load up the alertpipe */
03373    if (AST_LIST_FIRST(&clone->readq)) {
03374       AST_LIST_INSERT_TAIL(&clone->readq, AST_LIST_FIRST(&original->readq), frame_list);
03375       AST_LIST_HEAD_SET_NOLOCK(&original->readq, AST_LIST_FIRST(&clone->readq));
03376       AST_LIST_HEAD_SET_NOLOCK(&clone->readq, NULL);
03377       for (i = 0; i < x; i++)
03378          write(original->alertpipe[1], &x, sizeof(x));
03379    }
03380    
03381    clone->_softhangup = AST_SOFTHANGUP_DEV;
03382 
03383 
03384    /* And of course, so does our current state.  Note we need not
03385       call ast_setstate since the event manager doesn't really consider
03386       these separate.  We do this early so that the clone has the proper
03387       state of the original channel. */
03388    origstate = original->_state;
03389    original->_state = clone->_state;
03390    clone->_state = origstate;
03391 
03392    if (clone->tech->fixup){
03393       res = clone->tech->fixup(original, clone);
03394       if (res)
03395          ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clone->name);
03396    }
03397 
03398    /* Start by disconnecting the original's physical side */
03399    if (clone->tech->hangup)
03400       res = clone->tech->hangup(clone);
03401    if (res) {
03402       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
03403       ast_channel_unlock(clone);
03404       return -1;
03405    }
03406    
03407    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
03408    /* Mangle the name of the clone channel */
03409    ast_string_field_set(clone, name, zombn);
03410    manager_event(EVENT_FLAG_CALL, "Rename", "Oldname: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clone->uniqueid);
03411 
03412    /* Update the type. */
03413    t_pvt = original->monitor;
03414    original->monitor = clone->monitor;
03415    clone->monitor = t_pvt;
03416    
03417    /* Keep the same language.  */
03418    ast_string_field_set(original, language, clone->language);
03419    /* Copy the FD's other than the generator fd */
03420    for (x = 0; x < AST_MAX_FDS; x++) {
03421       if (x != AST_GENERATOR_FD)
03422          original->fds[x] = clone->fds[x];
03423    }
03424 
03425    /* move any whisperer over */
03426    ast_channel_whisper_stop(original);
03427    if (ast_test_flag(clone, AST_FLAG_WHISPER)) {
03428       original->whisper = clone->whisper;
03429       ast_set_flag(original, AST_FLAG_WHISPER);
03430       clone->whisper = NULL;
03431       ast_clear_flag(clone, AST_FLAG_WHISPER);
03432    }
03433 
03434    /* Move data stores over */
03435    if (AST_LIST_FIRST(&clone->datastores))
03436                 AST_LIST_INSERT_TAIL(&original->datastores, AST_LIST_FIRST(&clone->datastores), entry);
03437    AST_LIST_HEAD_INIT_NOLOCK(&clone->datastores);
03438 
03439    clone_variables(original, clone);
03440    AST_LIST_HEAD_INIT_NOLOCK(&clone->varshead);
03441    /* Presense of ADSI capable CPE follows clone */
03442    original->adsicpe = clone->adsicpe;
03443    /* Bridge remains the same */
03444    /* CDR fields remain the same */
03445    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
03446    /* Application and data remain the same */
03447    /* Clone exception  becomes real one, as with fdno */
03448    ast_copy_flags(original, clone, AST_FLAG_EXCEPTION);
03449    original->fdno = clone->fdno;
03450    /* Schedule context remains the same */
03451    /* Stream stuff stays the same */
03452    /* Keep the original state.  The fixup code will need to work with it most likely */
03453 
03454    /* Just swap the whole structures, nevermind the allocations, they'll work themselves
03455       out. */
03456    tmpcid = original->cid;
03457    original->cid = clone->cid;
03458    clone->cid = tmpcid;
03459    
03460    /* Restore original timing file descriptor */
03461    original->fds[AST_TIMING_FD] = original->timingfd;
03462    
03463    /* Our native formats are different now */
03464    original->nativeformats = clone->nativeformats;
03465    
03466    /* Context, extension, priority, app data, jump table,  remain the same */
03467    /* pvt switches.  pbx stays the same, as does next */
03468    
03469    /* Set the write format */
03470    ast_set_write_format(original, wformat);
03471 
03472    /* Set the read format */
03473    ast_set_read_format(original, rformat);
03474 
03475    /* Copy the music class */
03476    ast_string_field_set(original, musicclass, clone->musicclass);
03477 
03478    if (option_debug)
03479       ast_log(LOG_DEBUG, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
03480 
03481    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
03482       can fix up everything as best as possible */
03483    if (original->tech->fixup) {
03484       res = original->tech->fixup(clone, original);
03485       if (res) {
03486          ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
03487