Thu Apr 8 01:22:12 2010

Asterisk developer's documentation


channel.c File Reference

Channel Management. More...

#include "asterisk.h"
#include "asterisk/_private.h"
#include <sys/time.h>
#include <signal.h>
#include <math.h>
#include "asterisk/paths.h"
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
#include "asterisk/mod_format.h"
#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/musiconhold.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 "asterisk/audiohook.h"
#include "asterisk/timing.h"
Include dependency graph for channel.c:

Go to the source code of this file.

Data Structures

struct  ast_cause
 map AST_CAUSE's to readable string representations More...
struct  ast_epoll_data
struct  ast_silence_generator
struct  chanlist
 List of channel drivers. More...
struct  tonepair_def
struct  tonepair_state

Defines

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

Functions

int __ast_answer (struct ast_channel *chan, unsigned int delay, int cdr_answer)
 Answer a channel, with a selectable delay before returning.
struct ast_channel__ast_channel_alloc (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *file, int line, const char *function, const char *name_fmt,...)
 Create a channel structure.
static struct ast_channel
*attribute_malloc 
__ast_channel_alloc_ap (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *file, int line, const char *function, const char *name_fmt, va_list ap1, va_list ap2)
 Create a new channel structure.
static int __ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin, int head, struct ast_frame *after)
static struct ast_frame__ast_read (struct ast_channel *chan, int dropaudio)
struct ast_channel__ast_request_and_dial (const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
 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_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.
struct ast_channelast_bridged_channel (struct ast_channel *chan)
 Find bridged channel.
int ast_call (struct ast_channel *chan, char *addr, int timeout)
 Make a call.
struct ast_channelast_call_forward (struct ast_channel *caller, struct ast_channel *orig, int *timeout, int format, struct outgoing_helper *oh, int *outstate)
 Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated.
void ast_cancel_shutdown (void)
 Cancel a shutdown in progress.
const char * ast_cause2str (int cause)
 Gives the string form of a given hangup cause.
void ast_change_name (struct ast_channel *chan, char *newname)
 Change channel name.
struct ast_channelast_channel_alloc (int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *name_fmt,...)
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_cmpwhentohangup_tv (struct ast_channel *chan, struct timeval offset)
 Compare a offset with when to hangup channel.
int ast_channel_datastore_add (struct ast_channel *chan, struct ast_datastore *datastore)
 Add a datastore to a channel.
struct ast_datastoreast_channel_datastore_alloc (const struct ast_datastore_info *info, const char *uid)
 Create a channel data store object.
struct ast_datastoreast_channel_datastore_find (struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
 Find a datastore on a channel.
int ast_channel_datastore_free (struct ast_datastore *datastore)
 Free a channel data store object.
int ast_channel_datastore_inherit (struct ast_channel *from, struct ast_channel *to)
 Inherit datastores from a parent to a child.
int ast_channel_datastore_remove (struct ast_channel *chan, struct ast_datastore *datastore)
 Remove a datastore from a channel.
int ast_channel_defer_dtmf (struct ast_channel *chan)
 Set defer DTMF flag on channel.
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 *clonechan)
 Weird function made for call transfers.
int ast_channel_queryoption (struct ast_channel *chan, int option, void *data, int *datalen, int block)
const char * ast_channel_reason2str (int reason)
 return an english explanation of the code returned thru __ast_request_and_dial's 'outstate' argument
int ast_channel_register (const struct ast_channel_tech *tech)
 Register a new telephony channel in Asterisk.
int ast_channel_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen)
int ast_channel_sendurl (struct ast_channel *chan, const char *url)
void ast_channel_set_fd (struct ast_channel *chan, int which, int fd)
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.
void ast_channel_setwhentohangup_tv (struct ast_channel *chan, struct timeval offset)
 Set when to hangup channel.
struct ast_silence_generatorast_channel_start_silence_generator (struct ast_channel *chan)
 Starts a silence generator on the given channel.
void ast_channel_stop_silence_generator (struct ast_channel *chan, struct ast_silence_generator *state)
 Stops a previously-started silence generator on the given channel.
int ast_channel_supports_html (struct ast_channel *chan)
void ast_channel_undefer_dtmf (struct ast_channel *chan)
 Unset defer DTMF flag on channel.
void ast_channel_unregister (const struct ast_channel_tech *tech)
 Unregister channel driver.
struct ast_channelast_channel_walk_locked (const struct ast_channel *prev)
 Browse channels in use.
void ast_channels_init (void)
struct ast_variableast_channeltype_list (void)
 return an ast_variable list of channeltypes
int ast_check_hangup (struct ast_channel *chan)
 Checks to see if a channel is needing hang up.
static int ast_check_hangup_locked (struct ast_channel *chan)
void ast_deactivate_generator (struct ast_channel *chan)
int ast_do_masquerade (struct ast_channel *original)
 Masquerade a channel.
static enum ast_bridge_result ast_generic_bridge (struct ast_channel *c0, struct ast_channel *c1, struct ast_bridge_config *config, struct ast_frame **fo, struct ast_channel **rc, struct timeval bridge_end)
struct ast_channelast_get_channel_by_exten_locked (const char *exten, const char *context)
 Get channel by exten (and optionally context) and lock it.
struct ast_channelast_get_channel_by_name_locked (const char *name)
 Get channel by name and lock it.
struct ast_channelast_get_channel_by_name_prefix_locked (const char *name, const int namelen)
 Get channel by name prefix and lock it.
struct ast_channel_techast_get_channel_tech (const char *name)
 Get handle to channel driver based on name.
ast_group_t ast_get_group (const char *s)
int ast_hangup (struct ast_channel *chan)
 Hangup a channel.
int ast_indicate (struct ast_channel *chan, int condition)
 Indicates condition of channel.
int ast_indicate_data (struct ast_channel *chan, int _condition, const void *data, size_t datalen)
 Indicates condition of channel, with payload.
void ast_install_music_functions (int(*start_ptr)(struct ast_channel *, const char *, const char *), void(*stop_ptr)(struct ast_channel *), void(*cleanup_ptr)(struct ast_channel *))
int ast_internal_timing_enabled (struct ast_channel *chan)
 Check if the channel can run in internal timing mode.
static AST_LIST_HEAD_NOLOCK_STATIC (backends, chanlist)
 the list of registered channel types
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.
void ast_poll_channel_add (struct ast_channel *chan0, struct ast_channel *chan1)
void ast_poll_channel_del (struct ast_channel *chan0, struct ast_channel *chan1)
char * ast_print_group (char *buf, int buflen, ast_group_t group)
 Print call group and pickup group ---.
int ast_prod (struct ast_channel *chan)
 Send empty audio to prime a channel driver.
int ast_queue_control (struct ast_channel *chan, enum ast_control_frame_type control)
 Queue a control frame.
int ast_queue_control_data (struct ast_channel *chan, enum ast_control_frame_type control, const void *data, size_t datalen)
 Queue a control frame with payload.
int ast_queue_frame (struct ast_channel *chan, struct ast_frame *fin)
 Queue one or more frames to a channel's frame queue.
int ast_queue_frame_head (struct ast_channel *chan, struct ast_frame *fin)
 Queue one or more frames to the head of a channel's frame queue.
int ast_queue_hangup (struct ast_channel *chan)
 Queue a hangup frame for channel.
int ast_queue_hangup_with_cause (struct ast_channel *chan, int cause)
 Queue a hangup frame for channel.
int ast_raw_answer (struct ast_channel *chan, int cdr_answer)
 Answer a channel.
struct ast_frameast_read (struct ast_channel *chan)
 Reads a frame.
static void ast_read_generator_actions (struct ast_channel *chan, struct ast_frame *f)
struct ast_frameast_read_noaudio (struct ast_channel *chan)
 Reads a frame, returning AST_FRAME_NULL frame if audio.
int ast_readstring (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
int ast_readstring_full (struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
int ast_recvchar (struct ast_channel *chan, int timeout)
 Receives a text character from a channel.
char * ast_recvtext (struct ast_channel *chan, int timeout)
 Receives a text string from a channel Read a string of text from a channel.
struct ast_channelast_request (const char *type, int format, void *data, int *cause)
 Requests a channel.
struct ast_channelast_request_and_dial (const char *type, int format, void *data, int timeout, int *outstate, 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.
static AST_RWLIST_HEAD_STATIC (channels, ast_channel)
 the list of channels we have. Note that the lock for this list is used for both the channels list and the backends list.
int ast_safe_sleep (struct ast_channel *chan, int ms)
 Wait, look for hangups.
int ast_safe_sleep_conditional (struct ast_channel *chan, int ms, int(*cond)(void *), void *data)
 Wait, look for hangups and condition arg.
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, unsigned int duration)
 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.
void ast_set_callerid (struct ast_channel *chan, const char *cid_num, const char *cid_name, const char *cid_ani)
 Set caller ID number, name and 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, unsigned int rate, int(*func)(const void *data), void *data)
 Enable or disable timer ticks for a channel.
int ast_shutting_down (void)
 Returns non-zero if Asterisk is being shut down.
int ast_softhangup (struct ast_channel *chan, int cause)
 Softly hangup a channel, lock.
int ast_softhangup_nolock (struct ast_channel *chan, int cause)
 Softly hangup a channel, don't lock.
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 call to dest, if the channel supports transfer.
char * ast_transfercapability2str (int transfercapability)
 Gives the string form of a given transfer capability.
void ast_uninstall_music_functions (void)
int ast_waitfor (struct ast_channel *c, int ms)
 Wait for input on a channel.
struct ast_channelast_waitfor_n (struct ast_channel **c, int n, int *ms)
 Waits for input on a group of channels Wait for input on an array of channels for a given # of milliseconds.
int ast_waitfor_n_fd (int *fds, int n, int *ms, int *exception)
 Wait for x amount of time on a file descriptor to have input.
struct ast_channelast_waitfor_nandfds (struct ast_channel **c, int n, int *fds, int nfds, int *exception, int *outfd, int *ms)
 Wait for x amount of time on a file descriptor to have input.
int ast_waitfordigit (struct ast_channel *c, int ms)
 Waits for a digit.
int ast_waitfordigit_full (struct ast_channel *c, int ms, int audiofd, int cmdfd)
 Wait for a digit Same as ast_waitfordigit() with audio fd for outputting read audio and ctrlfd to monitor for reading.
struct ast_channelast_walk_channel_by_exten_locked (const struct ast_channel *chan, const char *exten, const char *context)
 Get next channel by exten (and optionally context) and lock it.
struct ast_channelast_walk_channel_by_name_prefix_locked (const struct ast_channel *chan, const char *name, const int namelen)
 Get next channel by name prefix and lock it.
int ast_write (struct ast_channel *chan, struct ast_frame *fr)
 Write a frame to a channel This function writes the given frame to the indicated channel.
int ast_write_video (struct ast_channel *chan, struct ast_frame *fr)
 Write video frame to a channel This function writes the given frame to the indicated channel.
static void bridge_play_sounds (struct ast_channel *c0, struct ast_channel *c1)
static void bridge_playfile (struct ast_channel *chan, struct ast_channel *peer, const char *sound, int remain)
static int calc_monitor_jump (int samples, int sample_rate, int seek_rate)
 calculates the number of samples to jump forward with in a monitor stream.
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 *clonechan)
 Clone channel variables from 'clone' channel into 'original' channel.
static char * complete_channeltypes (struct ast_cli_args *a)
static void free_cid (struct ast_callerid *cid)
static void free_translation (struct ast_channel *clonechan)
static int generator_force (const void *data)
static void handle_cause (int cause, int *outstate)
static char * handle_cli_core_show_channeltype (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show details about a channel driver - CLI command.
static char * handle_cli_core_show_channeltypes (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 Show channel types - CLI command.
static int attribute_const is_visible_indication (enum ast_control_frame_type condition)
static void manager_bridge_event (int onoff, int type, struct ast_channel *c0, struct ast_channel *c1)
 Send manager event for bridge link and unlink events.
static void queue_dtmf_readq (struct ast_channel *chan, struct ast_frame *f)
static void report_new_callerid (const struct ast_channel *chan)
static void send_dtmf_event (const struct ast_channel *chan, const char *direction, const char digit, const char *begin, const char *end)
static int set_format (struct ast_channel *chan, int fmt, int *rawformat, int *format, struct ast_trans_pvt **trans, const int direction)
static int should_skip_dtmf (struct ast_channel *chan)
 Determine whether or not we should ignore DTMF in the readq.
static void * silence_generator_alloc (struct ast_channel *chan, void *data)
static int silence_generator_generate (struct ast_channel *chan, void *data, int len, int samples)
static void silence_generator_release (struct ast_channel *chan, void *data)
static void * tonepair_alloc (struct ast_channel *chan, void *params)
static int tonepair_generator (struct ast_channel *chan, void *data, int len, int samples)
static void tonepair_release (struct ast_channel *chan, void *params)
static void update_bridge_vars (struct ast_channel *c0, struct ast_channel *c1)

Variables

static void(* ast_moh_cleanup_ptr )(struct ast_channel *) = NULL
static int(* ast_moh_start_ptr )(struct ast_channel *, const char *, const char *) = NULL
static void(* ast_moh_stop_ptr )(struct ast_channel *) = NULL
struct ast_cause causes []
 map AST_CAUSE's to readable string representations
static struct ast_cli_entry cli_channel []
unsigned long global_fin
unsigned long global_fout
static struct ast_channel_tech null_tech
static int shutting_down
 Prevent new channel allocation if shutting down.
static struct ast_generator silence_generator
static struct ast_generator tonepair
static int uniqueint

Detailed Description

Channel Management.

Author:
Mark Spencer <markster@digium.com>

Definition in file channel.c.


Define Documentation

#define AST_DEFAULT_EMULATE_DTMF_DURATION   100

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

Definition at line 93 of file channel.c.

Referenced by __ast_read(), and ast_senddigit().

#define AST_MIN_DTMF_DURATION   80

Minimum allowed digit length - 80ms

Definition at line 96 of file channel.c.

Referenced by __ast_read().

#define AST_MIN_DTMF_GAP   45

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

Definition at line 100 of file channel.c.

Referenced by __ast_read(), and should_skip_dtmf().

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

Definition at line 89 of file channel.c.

Referenced by ast_state2str().


Function Documentation

int __ast_answer ( struct ast_channel chan,
unsigned int  delay,
int  cdr_answer 
)

Answer a channel, with a selectable delay before returning.

Parameters:
chan channel to answer
delay maximum amount of time to wait for incoming media
cdr_answer flag to control whether any associated CDR should be marked as 'answered'

This function answers a channel and handles all necessary call setup functions.

Note:
The channel passed does not need to be locked, but is locked by the function when needed.
This function will wait up to 'delay' milliseconds for media to arrive on the channel before returning to the caller, so that the caller can properly assume the channel is 'ready' for media flow. If 'delay' is less than 500, the function will wait up to 500 milliseconds.
Return values:
0 on success
non-zero on failure

Definition at line 1823 of file channel.c.

References ast_channel::_state, ast_channel_lock, ast_channel_unlock, AST_CONTROL_HANGUP, ast_debug, AST_FRAME_CNG, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_frisolate(), AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_HEAD, AST_LIST_REMOVE_HEAD, ast_log(), ast_queue_frame_head(), ast_raw_answer(), ast_read(), AST_STATE_RING, AST_STATE_RINGING, ast_waitfor(), errno, frames, ast_frame::frametype, LOG_WARNING, MAX, and ast_frame::subclass.

Referenced by ast_answer(), dial_exec_full(), pbx_builtin_answer(), and pbx_builtin_incomplete().

01824 {
01825    int res = 0;
01826    enum ast_channel_state old_state;
01827 
01828    old_state = chan->_state;
01829    if ((res = ast_raw_answer(chan, cdr_answer))) {
01830       return res;
01831    }
01832 
01833    switch (old_state) {
01834    case AST_STATE_RINGING:
01835    case AST_STATE_RING:
01836       /* wait for media to start flowing, but don't wait any longer
01837        * than 'delay' or 500 milliseconds, whichever is longer
01838        */
01839       do {
01840          AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
01841          struct ast_frame *cur, *new;
01842          int ms = MAX(delay, 500);
01843          unsigned int done = 0;
01844 
01845          AST_LIST_HEAD_INIT_NOLOCK(&frames);
01846 
01847          for (;;) {
01848             ms = ast_waitfor(chan, ms);
01849             if (ms < 0) {
01850                ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno));
01851                res = -1;
01852                break;
01853             }
01854             if (ms == 0) {
01855                ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500));
01856                break;
01857             }
01858             cur = ast_read(chan);
01859             if (!cur || ((cur->frametype == AST_FRAME_CONTROL) &&
01860                     (cur->subclass == AST_CONTROL_HANGUP))) {
01861                if (cur) {
01862                   ast_frfree(cur);
01863                }
01864                res = -1;
01865                ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name);
01866                break;
01867             }
01868 
01869             if ((new = ast_frisolate(cur)) != cur) {
01870                ast_frfree(cur);
01871             }
01872 
01873             AST_LIST_INSERT_HEAD(&frames, new, frame_list);
01874 
01875             /* if a specific delay period was requested, continue
01876              * until that delay has passed. don't stop just because
01877              * incoming media has arrived.
01878              */
01879             if (delay) {
01880                continue;
01881             }
01882 
01883             switch (new->frametype) {
01884                /* all of these frametypes qualify as 'media' */
01885             case AST_FRAME_VOICE:
01886             case AST_FRAME_VIDEO:
01887             case AST_FRAME_TEXT:
01888             case AST_FRAME_DTMF_BEGIN:
01889             case AST_FRAME_DTMF_END:
01890             case AST_FRAME_IMAGE:
01891             case AST_FRAME_HTML:
01892             case AST_FRAME_MODEM:
01893                done = 1;
01894                break;
01895             case AST_FRAME_CONTROL:
01896             case AST_FRAME_IAX:
01897             case AST_FRAME_NULL:
01898             case AST_FRAME_CNG:
01899                break;
01900             }
01901 
01902             if (done) {
01903                break;
01904             }
01905          }
01906 
01907          if (res == 0) {
01908             ast_channel_lock(chan);
01909             while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) {
01910                ast_queue_frame_head(chan, cur);
01911                ast_frfree(cur);
01912             }
01913             ast_channel_unlock(chan);
01914          }
01915       } while (0);
01916       break;
01917    default:
01918       break;
01919    }
01920 
01921    return res;
01922 }

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

Create a channel structure.

Return values:
NULL failure
non-NULL successfully allocated channel
Note:
By default, new channels are set to the "s" extension and "default" context.

Definition at line 967 of file channel.c.

References __ast_channel_alloc_ap().

00972 {
00973    va_list ap1, ap2;
00974    struct ast_channel *result;
00975 
00976    va_start(ap1, name_fmt);
00977    va_start(ap2, name_fmt);
00978    result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
00979                amaflag, file, line, function, name_fmt, ap1, ap2);
00980    va_end(ap1);
00981    va_end(ap2);
00982 
00983    return result;
00984 }

static struct ast_channel* attribute_malloc __ast_channel_alloc_ap ( int  needqueue,
int  state,
const char *  cid_num,
const char *  cid_name,
const char *  acctcode,
const char *  exten,
const char *  context,
const int  amaflag,
const char *  file,
int  line,
const char *  function,
const char *  name_fmt,
va_list  ap1,
va_list  ap2 
) [static, read]

Create a new channel structure.

Definition at line 771 of file channel.c.

References __ast_calloc(), ast_channel::_state, accountcode, ast_channel::alertpipe, ast_channel::amaflags, AST_ALERT_FD, ast_atomic_fetchadd_int(), ast_calloc, ast_cdr_alloc(), ast_cdr_init(), ast_cdr_start(), ast_channel_set_fd(), ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_default_accountcode, ast_default_amaflags, AST_FLAG_IN_CHANNEL_LIST, ast_free, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), AST_MAX_FDS, ast_mutex_init(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_set_flag, ast_state2str(), ast_strdup, ast_string_field_build, ast_string_field_build_va, ast_string_field_free_memory, ast_string_field_init, ast_string_field_set, ast_strlen_zero(), ast_timer_close(), ast_timer_fd(), ast_timer_open(), AST_TIMING_FD, ast_channel::cdr, channels, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, defaultlanguage, errno, EVENT_FLAG_CALL, ast_channel::exten, ast_channel::fds, ast_channel::fin, chanlist::flags, ast_channel::fout, language, ast_channel::lock_dont_use, LOG_WARNING, manager_event, name, null_tech, ast_channel::priority, S_OR, ast_channel::sched, sched_context_create(), sched_context_destroy(), ast_channel::streamid, ast_channel::tech, ast_channel::timer, ast_channel::timingfd, and ast_channel::varshead.

Referenced by __ast_channel_alloc(), and ast_channel_alloc().

00775 {
00776    struct ast_channel *tmp;
00777    int x;
00778    int flags;
00779    struct varshead *headp;
00780 
00781    /* If shutting down, don't allocate any new channels */
00782    if (shutting_down) {
00783       ast_log(LOG_WARNING, "Channel allocation failed: Refusing due to active shutdown\n");
00784       return NULL;
00785    }
00786 
00787 #if defined(__AST_DEBUG_MALLOC)
00788    if (!(tmp = __ast_calloc(1, sizeof(*tmp), file, line, function))) {
00789       return NULL;
00790    }
00791 #else
00792    if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
00793       return NULL;
00794    }
00795 #endif
00796 
00797    if (!(tmp->sched = sched_context_create())) {
00798       ast_log(LOG_WARNING, "Channel allocation failed: Unable to create schedule context\n");
00799       ast_free(tmp);
00800       return NULL;
00801    }
00802    
00803    if ((ast_string_field_init(tmp, 128))) {
00804       sched_context_destroy(tmp->sched);
00805       ast_free(tmp);
00806       return NULL;
00807    }
00808 
00809 #ifdef HAVE_EPOLL
00810    tmp->epfd = epoll_create(25);
00811 #endif
00812 
00813    for (x = 0; x < AST_MAX_FDS; x++) {
00814       tmp->fds[x] = -1;
00815 #ifdef HAVE_EPOLL
00816       tmp->epfd_data[x] = NULL;
00817 #endif
00818    }
00819 
00820    if ((tmp->timer = ast_timer_open())) {
00821       needqueue = 0;
00822       tmp->timingfd = ast_timer_fd(tmp->timer);
00823    } else {
00824       tmp->timingfd = -1;
00825    }
00826 
00827    if (needqueue) {
00828       if (pipe(tmp->alertpipe)) {
00829          ast_log(LOG_WARNING, "Channel allocation failed: Can't create alert pipe! Try increasing max file descriptors with ulimit -n\n");
00830 alertpipe_failed:
00831          if (tmp->timer) {
00832             ast_timer_close(tmp->timer);
00833          }
00834 
00835          sched_context_destroy(tmp->sched);
00836          ast_string_field_free_memory(tmp);
00837          ast_free(tmp);
00838          return NULL;
00839       } else {
00840          flags = fcntl(tmp->alertpipe[0], F_GETFL);
00841          if (fcntl(tmp->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
00842             ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
00843             close(tmp->alertpipe[0]);
00844             close(tmp->alertpipe[1]);
00845             goto alertpipe_failed;
00846          }
00847          flags = fcntl(tmp->alertpipe[1], F_GETFL);
00848          if (fcntl(tmp->alertpipe[1], F_SETFL, flags | O_NONBLOCK) < 0) {
00849             ast_log(LOG_WARNING, "Channel allocation failed: Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
00850             close(tmp->alertpipe[0]);
00851             close(tmp->alertpipe[1]);
00852             goto alertpipe_failed;
00853          }
00854       }
00855    } else   /* Make sure we've got it done right if they don't */
00856       tmp->alertpipe[0] = tmp->alertpipe[1] = -1;
00857 
00858    /* Always watch the alertpipe */
00859    ast_channel_set_fd(tmp, AST_ALERT_FD, tmp->alertpipe[0]);
00860    /* And timing pipe */
00861    ast_channel_set_fd(tmp, AST_TIMING_FD, tmp->timingfd);
00862    ast_string_field_set(tmp, name, "**Unknown**");
00863 
00864    /* Initial state */
00865    tmp->_state = state;
00866 
00867    tmp->streamid = -1;
00868    
00869    tmp->fin = global_fin;
00870    tmp->fout = global_fout;
00871 
00872    if (ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
00873       ast_string_field_build(tmp, uniqueid, "%li.%d", (long) time(NULL), 
00874                    ast_atomic_fetchadd_int(&uniqueint, 1));
00875    } else {
00876       ast_string_field_build(tmp, uniqueid, "%s-%li.%d", ast_config_AST_SYSTEM_NAME, 
00877                    (long) time(NULL), ast_atomic_fetchadd_int(&uniqueint, 1));
00878    }
00879 
00880    tmp->cid.cid_name = ast_strdup(cid_name);
00881    tmp->cid.cid_num = ast_strdup(cid_num);
00882    
00883    if (!ast_strlen_zero(name_fmt)) {
00884       /* Almost every channel is calling this function, and setting the name via the ast_string_field_build() call.
00885        * And they all use slightly different formats for their name string.
00886        * This means, to set the name here, we have to accept variable args, and call the string_field_build from here.
00887        * This means, that the stringfields must have a routine that takes the va_lists directly, and 
00888        * uses them to build the string, instead of forming the va_lists internally from the vararg ... list.
00889        * This new function was written so this can be accomplished.
00890        */
00891       ast_string_field_build_va(tmp, name, name_fmt, ap1, ap2);
00892    }
00893 
00894    /* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */
00895 
00896    /* These 4 variables need to be set up for the cdr_init() to work right */
00897    if (amaflag)
00898       tmp->amaflags = amaflag;
00899    else
00900       tmp->amaflags = ast_default_amaflags;
00901    
00902    if (!ast_strlen_zero(acctcode))
00903       ast_string_field_set(tmp, accountcode, acctcode);
00904    else
00905       ast_string_field_set(tmp, accountcode, ast_default_accountcode);
00906       
00907    if (!ast_strlen_zero(context))
00908       ast_copy_string(tmp->context, context, sizeof(tmp->context));
00909    else
00910       strcpy(tmp->context, "default");
00911 
00912    if (!ast_strlen_zero(exten))
00913       ast_copy_string(tmp->exten, exten, sizeof(tmp->exten));
00914    else
00915       strcpy(tmp->exten, "s");
00916 
00917    tmp->priority = 1;
00918       
00919    tmp->cdr = ast_cdr_alloc();
00920    ast_cdr_init(tmp->cdr, tmp);
00921    ast_cdr_start(tmp->cdr);
00922    
00923    headp = &tmp->varshead;
00924    AST_LIST_HEAD_INIT_NOLOCK(headp);
00925    
00926    ast_mutex_init(&tmp->lock_dont_use);
00927    
00928    AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores);
00929    
00930    ast_string_field_set(tmp, language, defaultlanguage);
00931 
00932    tmp->tech = &null_tech;
00933 
00934    ast_set_flag(tmp, AST_FLAG_IN_CHANNEL_LIST);
00935 
00936    AST_RWLIST_WRLOCK(&channels);
00937    AST_RWLIST_INSERT_HEAD(&channels, tmp, chan_list);
00938    AST_RWLIST_UNLOCK(&channels);
00939 
00940    /*\!note
00941     * and now, since the channel structure is built, and has its name, let's
00942     * call the manager event generator with this Newchannel event. This is the
00943     * proper and correct place to make this call, but you sure do have to pass
00944     * a lot of data into this func to do it here!
00945     */
00946    if (!ast_strlen_zero(name_fmt)) {
00947       manager_event(EVENT_FLAG_CALL, "Newchannel",
00948          "Channel: %s\r\n"
00949          "ChannelState: %d\r\n"
00950          "ChannelStateDesc: %s\r\n"
00951          "CallerIDNum: %s\r\n"
00952          "CallerIDName: %s\r\n"
00953          "AccountCode: %s\r\n"
00954          "Uniqueid: %s\r\n",
00955          tmp->name, 
00956          state, 
00957          ast_state2str(state),
00958          S_OR(cid_num, ""),
00959          S_OR(cid_name, ""),
00960          tmp->accountcode,
00961          tmp->uniqueid);
00962    }
00963 
00964    return tmp;
00965 }

static int __ast_queue_frame ( struct ast_channel chan,
struct ast_frame fin,
int  head,
struct ast_frame after 
) [static]

Definition at line 986 of file channel.c.

References ast_channel::alertpipe, ast_channel_lock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FLAG_BLOCKING, AST_FRAME_CONTROL, AST_FRAME_NULL, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frdup(), ast_frfree, AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_HEAD_NOLOCK, AST_LIST_INSERT_LIST_AFTER, AST_LIST_INSERT_TAIL, AST_LIST_LAST, AST_LIST_NEXT, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), ast_test_flag, ast_timer_enable_continuous(), ast_channel::blocker, errno, f, frames, ast_frame::frametype, LOG_WARNING, ast_frame::subclass, ast_channel::timer, and ast_channel::timingfd.

Referenced by __ast_read(), ast_queue_frame(), and ast_queue_frame_head().

00987 {
00988    struct ast_frame *f;
00989    struct ast_frame *cur;
00990    int blah = 1;
00991    unsigned int new_frames = 0;
00992    unsigned int new_voice_frames = 0;
00993    unsigned int queued_frames = 0;
00994    unsigned int queued_voice_frames = 0;
00995    AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
00996 
00997    ast_channel_lock(chan);
00998 
00999    /* See if the last frame on the queue is a hangup, if so don't queue anything */
01000    if ((cur = AST_LIST_LAST(&chan->readq)) &&
01001        (cur->frametype == AST_FRAME_CONTROL) &&
01002        (cur->subclass == AST_CONTROL_HANGUP)) {
01003       ast_channel_unlock(chan);
01004       return 0;
01005    }
01006 
01007    /* Build copies of all the frames and count them */
01008    AST_LIST_HEAD_INIT_NOLOCK(&frames);
01009    for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
01010       if (!(f = ast_frdup(cur))) {
01011          ast_frfree(AST_LIST_FIRST(&frames));
01012          ast_channel_unlock(chan);
01013          return -1;
01014       }
01015 
01016       AST_LIST_INSERT_TAIL(&frames, f, frame_list);
01017       new_frames++;
01018       if (f->frametype == AST_FRAME_VOICE) {
01019          new_voice_frames++;
01020       }
01021    }
01022 
01023    /* Count how many frames exist on the queue */
01024    AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) {
01025       queued_frames++;
01026       if (cur->frametype == AST_FRAME_VOICE) {
01027          queued_voice_frames++;
01028       }
01029    }
01030 
01031    if ((queued_frames + new_frames > 128 || queued_voice_frames + new_voice_frames > 96)) {
01032       int count = 0;
01033       ast_log(LOG_WARNING, "Exceptionally long %squeue length queuing to %s\n", queued_frames + new_frames > 128 ? "" : "voice ", chan->name);
01034       AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, cur, frame_list) {
01035          /* Save the most recent frame */
01036          if (!AST_LIST_NEXT(cur, frame_list)) {
01037             break;
01038          } else if (cur->frametype == AST_FRAME_VOICE || cur->frametype == AST_FRAME_VIDEO || cur->frametype == AST_FRAME_NULL) {
01039             if (++count > 64) {
01040                break;
01041             }
01042             AST_LIST_REMOVE_CURRENT(frame_list);
01043             ast_frfree(cur);
01044          }
01045       }
01046       AST_LIST_TRAVERSE_SAFE_END;
01047    }
01048 
01049    if (after) {
01050       AST_LIST_INSERT_LIST_AFTER(&chan->readq, &frames, after, frame_list);
01051    } else {
01052       if (head) {
01053          AST_LIST_APPEND_LIST(&frames, &chan->readq, frame_list);
01054          AST_LIST_HEAD_INIT_NOLOCK(&chan->readq);
01055       }
01056       AST_LIST_APPEND_LIST(&chan->readq, &frames, frame_list);
01057    }
01058 
01059    if (chan->alertpipe[1] > -1) {
01060       if (write(chan->alertpipe[1], &blah, new_frames * sizeof(blah)) != (new_frames * sizeof(blah))) {
01061          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s (qlen = %d): %s!\n",
01062             chan->name, queued_frames, strerror(errno));
01063       }
01064    } else if (chan->timingfd > -1) {
01065       ast_timer_enable_continuous(chan->timer);
01066    } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01067       pthread_kill(chan->blocker, SIGURG);
01068    }
01069 
01070    ast_channel_unlock(chan);
01071 
01072    return 0;
01073 }

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

Todo:
XXX It is possible to write a digit to the audiohook twice if the digit was originally read while the channel was in autoservice.

Definition at line 2609 of file channel.c.

References __ast_queue_frame(), ast_channel::_softhangup, ast_channel::_state, ast_channel::alertpipe, AST_AUDIOHOOK_DIRECTION_READ, ast_audiohook_write_list(), ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_ANSWER, AST_CONTROL_HANGUP, ast_deactivate_generator(), ast_debug, 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_format_rate(), AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree, AST_GENERATOR_FD, ast_getformatname(), ast_getformatname_multiple(), AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_LAST, AST_LIST_NEXT, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_MIN_DTMF_DURATION, AST_MIN_DTMF_GAP, AST_MONITOR_RUNNING, ast_null_frame, ast_queue_frame(), ast_queue_frame_head(), ast_read_generator_actions(), ast_seekstream(), ast_set_flag, ast_setstate(), AST_SOFTHANGUP_DEV, AST_STATE_UP, ast_test_flag, ast_timer_ack(), ast_timer_disable_continuous(), ast_timer_get_event(), ast_timer_set_rate(), AST_TIMING_EVENT_CONTINUOUS, AST_TIMING_EVENT_EXPIRED, AST_TIMING_FD, ast_translate(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_writestream(), ast_channel::audiohooks, ast_channel::blocker, calc_monitor_jump(), ast_frame::data, DEBUGCHAN_FLAG, ast_generator::digit, ast_channel::dtmf_tv, ast_channel::dtmff, ast_channel::emulate_dtmf_digit, ast_channel::emulate_dtmf_duration, errno, ast_channel_tech::exception, f, ast_channel::fdno, ast_channel::fds, ast_channel::fin, chanlist::flags, ast_filestream::fmt, ast_format::format, FRAMECOUNT_INC, ast_frame::frametype, ast_generator::generate, ast_channel::generator, ast_channel::generatordata, ast_channel::hangupcause, ast_channel::insmpl, ast_frame::len, LOG_DTMF, LOG_ERROR, LOG_NOTICE, LOG_WARNING, ast_channel::masq, ast_channel::monitor, ast_channel::music_state, ast_channel::nativeformats, ast_channel::outsmpl, queue_dtmf_readq(), ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readtrans, ast_frame::samples, SEEK_FORCECUR, send_dtmf_event(), should_skip_dtmf(), ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel::timer, ast_channel::timingdata, ast_channel::timingfd, ast_channel::timingfunc, and ast_frame::uint32.

Referenced by ast_read(), and ast_read_noaudio().

02610 {
02611    struct ast_frame *f = NULL;   /* the return value */
02612    int blah;
02613    int prestate;
02614    int count = 0, cause = 0;
02615 
02616    /* this function is very long so make sure there is only one return
02617     * point at the end (there are only two exceptions to this).
02618     */
02619    while(ast_channel_trylock(chan)) {
02620       if(count++ > 10) 
02621          /*cannot goto done since the channel is not locked*/
02622          return &ast_null_frame;
02623       usleep(1);
02624    }
02625 
02626    if (chan->masq) {
02627       if (ast_do_masquerade(chan))
02628          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02629       else
02630          f =  &ast_null_frame;
02631       goto done;
02632    }
02633 
02634    /* Stop if we're a zombie or need a soft hangup */
02635    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
02636       if (chan->generator)
02637          ast_deactivate_generator(chan);
02638       goto done;
02639    }
02640 
02641 #ifdef AST_DEVMODE
02642    /* 
02643     * The ast_waitfor() code records which of the channel's file descriptors reported that
02644     * data is available.  In theory, ast_read() should only be called after ast_waitfor()
02645     * reports that a channel has data available for reading.  However, there still may be
02646     * some edge cases throughout the code where ast_read() is called improperly.  This can
02647     * potentially cause problems, so if this is a developer build, make a lot of noise if
02648     * this happens so that it can be addressed. 
02649     */
02650    if (chan->fdno == -1) {
02651       ast_log(LOG_ERROR, "ast_read() called with no recorded file descriptor.\n");
02652    }
02653 #endif
02654 
02655    prestate = chan->_state;
02656 
02657    /* Read and ignore anything on the alertpipe, but read only
02658       one sizeof(blah) per frame that we send from it */
02659    if (chan->alertpipe[0] > -1) {
02660       int flags = fcntl(chan->alertpipe[0], F_GETFL);
02661       /* For some odd reason, the alertpipe occasionally loses nonblocking status,
02662        * which immediately causes a deadlock scenario.  Detect and prevent this. */
02663       if ((flags & O_NONBLOCK) == 0) {
02664          ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", chan->name);
02665          if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
02666             ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
02667             f = &ast_null_frame;
02668             goto done;
02669          }
02670       }
02671       if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) {
02672          if (errno != EINTR && errno != EAGAIN)
02673             ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
02674       }
02675    }
02676 
02677    if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD) {
02678       enum ast_timer_event res;
02679 
02680       ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02681 
02682       res = ast_timer_get_event(chan->timer);
02683 
02684       switch (res) {
02685       case AST_TIMING_EVENT_EXPIRED:
02686          ast_timer_ack(chan->timer, 1);
02687 
02688          if (chan->timingfunc) {
02689             /* save a copy of func/data before unlocking the channel */
02690             int (*func)(const void *) = chan->timingfunc;
02691             void *data = chan->timingdata;
02692             chan->fdno = -1;
02693             ast_channel_unlock(chan);
02694             func(data);
02695          } else {
02696             ast_timer_set_rate(chan->timer, 0);
02697             chan->fdno = -1;
02698             ast_channel_unlock(chan);
02699          }
02700 
02701          /* cannot 'goto done' because the channel is already unlocked */
02702          return &ast_null_frame;
02703 
02704       case AST_TIMING_EVENT_CONTINUOUS:
02705          if (AST_LIST_EMPTY(&chan->readq) || 
02706             !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
02707             ast_timer_disable_continuous(chan->timer);
02708          }
02709          break;
02710       }
02711 
02712    } else if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
02713       /* if the AST_GENERATOR_FD is set, call the generator with args
02714        * set to -1 so it can do whatever it needs to.
02715        */
02716       void *tmp = chan->generatordata;
02717       chan->generatordata = NULL;     /* reset to let ast_write get through */
02718       chan->generator->generate(chan, tmp, -1, -1);
02719       chan->generatordata = tmp;
02720       f = &ast_null_frame;
02721       chan->fdno = -1;
02722       goto done;
02723    }
02724 
02725    /* Check for pending read queue */
02726    if (!AST_LIST_EMPTY(&chan->readq)) {
02727       int skip_dtmf = should_skip_dtmf(chan);
02728 
02729       AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) {
02730          /* We have to be picky about which frame we pull off of the readq because
02731           * there are cases where we want to leave DTMF frames on the queue until
02732           * some later time. */
02733 
02734          if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
02735             continue;
02736          }
02737 
02738          AST_LIST_REMOVE_CURRENT(frame_list);
02739          break;
02740       }
02741       AST_LIST_TRAVERSE_SAFE_END;
02742       
02743       if (!f) {
02744          /* There were no acceptable frames on the readq. */
02745          f = &ast_null_frame;
02746          if (chan->alertpipe[0] > -1) {
02747             int poke = 0;
02748             /* Restore the state of the alertpipe since we aren't ready for any
02749              * of the frames in the readq. */
02750             if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) {
02751                ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno));
02752             }
02753          }
02754       }
02755 
02756       /* Interpret hangup and return NULL */
02757       /* XXX why not the same for frames from the channel ? */
02758       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
02759          cause = f->data.uint32;
02760          ast_frfree(f);
02761          f = NULL;
02762       }
02763    } else {
02764       chan->blocker = pthread_self();
02765       if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
02766          if (chan->tech->exception)
02767             f = chan->tech->exception(chan);
02768          else {
02769             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
02770             f = &ast_null_frame;
02771          }
02772          /* Clear the exception flag */
02773          ast_clear_flag(chan, AST_FLAG_EXCEPTION);
02774       } else if (chan->tech->read)
02775          f = chan->tech->read(chan);
02776       else
02777          ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
02778    }
02779 
02780    /*
02781     * Reset the recorded file descriptor that triggered this read so that we can
02782     * easily detect when ast_read() is called without properly using ast_waitfor().
02783     */
02784    chan->fdno = -1;
02785 
02786    if (f) {
02787       struct ast_frame *readq_tail = AST_LIST_LAST(&chan->readq);
02788 
02789       /* if the channel driver returned more than one frame, stuff the excess
02790          into the readq for the next ast_read call
02791       */
02792       if (AST_LIST_NEXT(f, frame_list)) {
02793          ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list));
02794          ast_frfree(AST_LIST_NEXT(f, frame_list));
02795          AST_LIST_NEXT(f, frame_list) = NULL;
02796       }
02797 
02798       switch (f->frametype) {
02799       case AST_FRAME_CONTROL:
02800          if (f->subclass == AST_CONTROL_ANSWER) {
02801             if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
02802                ast_debug(1, "Ignoring answer on an inbound call!\n");
02803                ast_frfree(f);
02804                f = &ast_null_frame;
02805             } else if (prestate == AST_STATE_UP) {
02806                ast_debug(1, "Dropping duplicate answer!\n");
02807                ast_frfree(f);
02808                f = &ast_null_frame;
02809             } else {
02810                /* Answer the CDR */
02811                ast_setstate(chan, AST_STATE_UP);
02812                /* removed a call to ast_cdr_answer(chan->cdr) from here. */
02813             }
02814          }
02815          break;
02816       case AST_FRAME_DTMF_END:
02817          send_dtmf_event(chan, "Received", f->subclass, "No", "Yes");
02818          ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass, chan->name, f->len);
02819          /* Queue it up if DTMF is deferred, or if DTMF emulation is forced. */
02820          if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
02821             queue_dtmf_readq(chan, f);
02822             ast_frfree(f);
02823             f = &ast_null_frame;
02824          } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
02825             if (!ast_tvzero(chan->dtmf_tv) && 
02826                 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
02827                /* If it hasn't been long enough, defer this digit */
02828                queue_dtmf_readq(chan, f);
02829                ast_frfree(f);
02830                f = &ast_null_frame;
02831             } else {
02832                /* There was no begin, turn this into a begin and send the end later */
02833                f->frametype = AST_FRAME_DTMF_BEGIN;
02834                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02835                chan->emulate_dtmf_digit = f->subclass;
02836                chan->dtmf_tv = ast_tvnow();
02837                if (f->len) {
02838                   if (f->len > AST_MIN_DTMF_DURATION)
02839                      chan->emulate_dtmf_duration = f->len;
02840                   else 
02841                      chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
02842                } else
02843                   chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
02844                ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass, chan->emulate_dtmf_duration, chan->name);
02845             }
02846             if (chan->audiohooks) {
02847                struct ast_frame *old_frame = f;
02848                /*!
02849                 * \todo XXX It is possible to write a digit to the audiohook twice
02850                 * if the digit was originally read while the channel was in autoservice. */
02851                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02852                if (old_frame != f)
02853                   ast_frfree(old_frame);
02854             }
02855          } else {
02856             struct timeval now = ast_tvnow();
02857             if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02858                ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass, chan->name);
02859                ast_clear_flag(chan, AST_FLAG_IN_DTMF);
02860                if (!f->len)
02861                   f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02862             } else if (!f->len) {
02863                ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass, chan->name);
02864                f->len = AST_MIN_DTMF_DURATION;
02865             }
02866             if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
02867                ast_log(LOG_DTMF, "DTMF end '%c' has duration %ld but want minimum %d, emulating on %s\n", f->subclass, f->len, AST_MIN_DTMF_DURATION, chan->name);
02868                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
02869                chan->emulate_dtmf_digit = f->subclass;
02870                chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
02871                ast_frfree(f);
02872                f = &ast_null_frame;
02873             } else {
02874                ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass, chan->name);
02875                if (f->len < AST_MIN_DTMF_DURATION) {
02876                   f->len = AST_MIN_DTMF_DURATION;
02877                }
02878                chan->dtmf_tv = now;
02879             }
02880             if (chan->audiohooks) {
02881                struct ast_frame *old_frame = f;
02882                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02883                if (old_frame != f)
02884                   ast_frfree(old_frame);
02885             }
02886          }
02887          break;
02888       case AST_FRAME_DTMF_BEGIN:
02889          send_dtmf_event(chan, "Received", f->subclass, "Yes", "No");
02890          ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name);
02891          if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) || 
02892              (!ast_tvzero(chan->dtmf_tv) && 
02893                ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
02894             ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass, chan->name);
02895             ast_frfree(f);
02896             f = &ast_null_frame;
02897          } else {
02898             ast_set_flag(chan, AST_FLAG_IN_DTMF);
02899             chan->dtmf_tv = ast_tvnow();
02900             ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass, chan->name);
02901          }
02902          break;
02903       case AST_FRAME_NULL:
02904          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
02905           * is reached , because we want to make sure we pass at least one
02906           * voice frame through before starting the next digit, to ensure a gap
02907           * between DTMF digits. */
02908          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
02909             struct timeval now = ast_tvnow();
02910             if (!chan->emulate_dtmf_duration) {
02911                ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02912                chan->emulate_dtmf_digit = 0;
02913             } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
02914                chan->emulate_dtmf_duration = 0;
02915                ast_frfree(f);
02916                f = &chan->dtmff;
02917                f->frametype = AST_FRAME_DTMF_END;
02918                f->subclass = chan->emulate_dtmf_digit;
02919                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02920                chan->dtmf_tv = now;
02921                ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02922                chan->emulate_dtmf_digit = 0;
02923                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
02924                if (chan->audiohooks) {
02925                   struct ast_frame *old_frame = f;
02926                   f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02927                   if (old_frame != f) {
02928                      ast_frfree(old_frame);
02929                   }
02930                }
02931             }
02932          }
02933          break;
02934       case AST_FRAME_VOICE:
02935          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
02936           * is reached , because we want to make sure we pass at least one
02937           * voice frame through before starting the next digit, to ensure a gap
02938           * between DTMF digits. */
02939          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
02940             ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
02941             chan->emulate_dtmf_digit = 0;
02942          }
02943 
02944          if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02945             if (dropaudio)
02946                ast_read_generator_actions(chan, f);
02947             ast_frfree(f);
02948             f = &ast_null_frame;
02949          }
02950 
02951          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
02952             struct timeval now = ast_tvnow();
02953             if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
02954                chan->emulate_dtmf_duration = 0;
02955                ast_frfree(f);
02956                f = &chan->dtmff;
02957                f->frametype = AST_FRAME_DTMF_END;
02958                f->subclass = chan->emulate_dtmf_digit;
02959                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
02960                chan->dtmf_tv = now;
02961                if (chan->audiohooks) {
02962                   struct ast_frame *old_frame = f;
02963                   f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02964                   if (old_frame != f)
02965                      ast_frfree(old_frame);
02966                }
02967                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
02968             } else {
02969                /* Drop voice frames while we're still in the middle of the digit */
02970                ast_frfree(f);
02971                f = &ast_null_frame;
02972             }
02973          } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass & chan->nativeformats)) {
02974             /* This frame is not one of the current native formats -- drop it on the floor */
02975             char to[200];
02976             ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
02977                chan->name, ast_getformatname(f->subclass), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats));
02978             ast_frfree(f);
02979             f = &ast_null_frame;
02980          } else if ((f->frametype == AST_FRAME_VOICE)) {
02981             /* Send frame to audiohooks if present */
02982             if (chan->audiohooks) {
02983                struct ast_frame *old_frame = f;
02984                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
02985                if (old_frame != f)
02986                   ast_frfree(old_frame);
02987             }
02988             if (chan->monitor && chan->monitor->read_stream ) {
02989                /* XXX what does this do ? */
02990 #ifndef MONITOR_CONSTANT_DELAY
02991                int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
02992                if (jump >= 0) {
02993                   jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass), ast_format_rate(chan->monitor->read_stream->fmt->format));
02994                   if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
02995                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
02996                   chan->insmpl += (chan->outsmpl - chan->insmpl) + f->samples;
02997                } else
02998                   chan->insmpl+= f->samples;
02999 #else
03000                int jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass), ast_format_rate(chan->monitor->read_stream->fmt->format));
03001                if (jump - MONITOR_DELAY >= 0) {
03002                   if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
03003                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
03004                   chan->insmpl += chan->outsmpl - chan->insmpl;
03005                } else
03006                   chan->insmpl += f->samples;
03007 #endif
03008                if (chan->monitor->state == AST_MONITOR_RUNNING) {
03009                   if (ast_writestream(chan->monitor->read_stream, f) < 0)
03010                      ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
03011                }
03012             }
03013 
03014             if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL) {
03015                f = &ast_null_frame;
03016             }
03017 
03018             /* it is possible for the translation process on chan->readtrans to have
03019                produced multiple frames from the single input frame we passed it; if
03020                this happens, queue the additional frames *before* the frames we may
03021                have queued earlier. if the readq was empty, put them at the head of
03022                the queue, and if it was not, put them just after the frame that was
03023                at the end of the queue.
03024             */
03025             if (AST_LIST_NEXT(f, frame_list)) {
03026                if (!readq_tail) {
03027                   ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list));
03028                } else {
03029                   __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail);
03030                }
03031                ast_frfree(AST_LIST_NEXT(f, frame_list));
03032                AST_LIST_NEXT(f, frame_list) = NULL;
03033             }
03034 
03035             /* Run generator sitting on the line if timing device not available
03036             * and synchronous generation of outgoing frames is necessary       */
03037             ast_read_generator_actions(chan, f);
03038          }
03039       default:
03040          /* Just pass it on! */
03041          break;
03042       }
03043    } else {
03044       /* Make sure we always return NULL in the future */
03045       chan->_softhangup |= AST_SOFTHANGUP_DEV;
03046       if (cause)
03047          chan->hangupcause = cause;
03048       if (chan->generator)
03049          ast_deactivate_generator(chan);
03050       /* We no longer End the CDR here */
03051    }
03052 
03053    /* High bit prints debugging */
03054    if (chan->fin & DEBUGCHAN_FLAG)
03055       ast_frame_dump(chan->name, f, "<<");
03056    chan->fin = FRAMECOUNT_INC(chan->fin);
03057 
03058 done:
03059    if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END)
03060       chan->generator->digit(chan, f->subclass);
03061 
03062    ast_channel_unlock(chan);
03063    return f;
03064 }

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

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

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

Definition at line 3823 of file channel.c.

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

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

03824 {
03825    int dummy_outstate;
03826    int cause = 0;
03827    struct ast_channel *chan;
03828    int res = 0;
03829    int last_subclass = 0;
03830    
03831    if (outstate)
03832       *outstate = 0;
03833    else
03834       outstate = &dummy_outstate;   /* make outstate always a valid pointer */
03835 
03836    chan = ast_request(type, format, data, &cause);
03837    if (!chan) {
03838       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
03839       handle_cause(cause, outstate);
03840       return NULL;
03841    }
03842 
03843    if (oh) {
03844       if (oh->vars)  
03845          ast_set_variables(chan, oh->vars);
03846       /* XXX why is this necessary, for the parent_channel perhaps ? */
03847       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
03848          ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
03849       if (oh->parent_channel) {
03850          ast_channel_inherit_variables(oh->parent_channel, chan);
03851          ast_channel_datastore_inherit(oh->parent_channel, chan);
03852       }
03853       if (oh->account)
03854          ast_cdr_setaccount(chan, oh->account); 
03855    }
03856    ast_set_callerid(chan, cid_num, cid_name, cid_num);
03857    ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
03858 
03859    if (ast_call(chan, data, 0)) {   /* ast_call failed... */
03860       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
03861    } else {
03862       res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
03863       while (timeout && chan->_state != AST_STATE_UP) {
03864          struct ast_frame *f;
03865          res = ast_waitfor(chan, timeout);
03866          if (res == 0) { /* timeout, treat it like ringing */
03867             *outstate = AST_CONTROL_RINGING;
03868             break;
03869          }
03870          if (res < 0) /* error or done */
03871             break;
03872          if (timeout > -1)
03873             timeout = res;
03874          if (!ast_strlen_zero(chan->call_forward)) {
03875             if (!(chan = ast_call_forward(NULL, chan, &timeout, format, oh, outstate))) {
03876                return NULL;
03877             }
03878             continue;
03879          }
03880 
03881          f = ast_read(chan);
03882          if (!f) {
03883             *outstate = AST_CONTROL_HANGUP;
03884             res = 0;
03885             break;
03886          }
03887          if (f->frametype == AST_FRAME_CONTROL) {
03888             switch (f->subclass) {
03889             case AST_CONTROL_RINGING:  /* record but keep going */
03890                *outstate = f->subclass;
03891                break;
03892 
03893             case AST_CONTROL_BUSY:
03894             case AST_CONTROL_CONGESTION:
03895             case AST_CONTROL_ANSWER:
03896                *outstate = f->subclass;
03897                timeout = 0;      /* trick to force exit from the while() */
03898                break;
03899 
03900             /* Ignore these */
03901             case AST_CONTROL_PROGRESS:
03902             case AST_CONTROL_PROCEEDING:
03903             case AST_CONTROL_HOLD:
03904             case AST_CONTROL_UNHOLD:
03905             case AST_CONTROL_VIDUPDATE:
03906             case AST_CONTROL_SRCUPDATE:
03907             case -1:       /* Ignore -- just stopping indications */
03908                break;
03909 
03910             default:
03911                ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
03912             }
03913             last_subclass = f->subclass;
03914          }
03915          ast_frfree(f);
03916       }
03917    }
03918 
03919    /* Final fixups */
03920    if (oh) {
03921       if (!ast_strlen_zero(oh->context))
03922          ast_copy_string(chan->context, oh->context, sizeof(chan->context));
03923       if (!ast_strlen_zero(oh->exten))
03924          ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
03925       if (oh->priority) 
03926          chan->priority = oh->priority;
03927    }
03928    if (chan->_state == AST_STATE_UP)
03929       *outstate = AST_CONTROL_ANSWER;
03930 
03931    if (res <= 0) {
03932       if ( AST_CONTROL_RINGING == last_subclass ) 
03933          chan->hangupcause = AST_CAUSE_NO_ANSWER;
03934       if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
03935          ast_cdr_init(chan->cdr, chan);
03936       if (chan->cdr) {
03937          char tmp[256];
03938          snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
03939          ast_cdr_setapp(chan->cdr,"Dial",tmp);
03940          ast_cdr_update(chan);
03941          ast_cdr_start(chan->cdr);
03942          ast_cdr_end(chan->cdr);
03943          /* If the cause wasn't handled properly */
03944          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
03945             ast_cdr_failed(chan->cdr);
03946       }
03947       ast_hangup(chan);
03948       chan = NULL;
03949    }
03950    return chan;
03951 }

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

Activate a given generator

Definition at line 1974 of file channel.c.

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

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

01975 {
01976    int res = 0;
01977 
01978    ast_channel_lock(chan);
01979 
01980    if (chan->generatordata) {
01981       if (chan->generator && chan->generator->release)
01982          chan->generator->release(chan, chan->generatordata);
01983       chan->generatordata = NULL;
01984    }
01985 
01986    ast_prod(chan);
01987    if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
01988       res = -1;
01989    }
01990    
01991    if (!res) {
01992       ast_settimeout(chan, 50, generator_force, chan);
01993       chan->generator = gen;
01994    }
01995 
01996    ast_channel_unlock(chan);
01997 
01998    return res;
01999 }

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns number of active/allocated channels

Definition at line 498 of file channel.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, and channels.

Referenced by action_corestatus(), dahdi_restart(), handle_show_settings(), and quit_handler().

00499 {
00500    struct ast_channel *c;
00501    int cnt = 0;
00502    AST_RWLIST_RDLOCK(&channels);
00503    AST_RWLIST_TRAVERSE(&channels, c, chan_list)
00504       cnt++;
00505    AST_RWLIST_UNLOCK(&channels);
00506    return cnt;
00507 }

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.

Note:
The channel passed does not need to be locked, but is locked by the function when needed.
This function will wait up to 500 milliseconds for media to arrive on the channel before returning to the caller, so that the caller can properly assume the channel is 'ready' for media flow.
Return values:
0 on success
non-zero on failure

Definition at line 1924 of file channel.c.

References __ast_answer().

Referenced by action_bridge(), agi_exec_full(), alarmreceiver_exec(), answer_trunk_chan(), app_exec(), ast_control_streamfile(), ast_pickup_call(), auth_exec(), background_detect_exec(), bridge_exec(), builtin_parkcall(), common_exec(), conf_exec(), count_exec(), dahdiras_exec(), dictate_exec(), directory_exec(), disa_exec(), eivr_comm(), handle_answer(), ices_exec(), login_exec(), minivm_accmess_exec(), minivm_greet_exec(), minivm_record_exec(), old_milliwatt_exec(), park_call_exec(), park_exec_full(), pbx_builtin_background(), pickup_do(), playback_exec(), privacy_exec(), read_exec(), readexten_exec(), record_exec(), rpt_exec(), sayunixtime_exec(), send_waveform_to_channel(), setup_privacy_args(), skel_exec(), sla_station_exec(), speech_background(), testclient_exec(), testserver_exec(), transmit(), vm_exec(), vm_execmain(), waitfor_exec(), and zapateller_exec().

01925 {
01926    return __ast_answer(chan, 0, 1);
01927 }

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

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_softhangup(), AST_SOFTHANGUP_SHUTDOWN, and channels.

Referenced by quit_handler().

00485 {
00486    struct ast_channel *c;
00487    shutting_down = 1;
00488    if (hangup) {
00489       AST_RWLIST_RDLOCK(&channels);
00490       AST_RWLIST_TRAVERSE(&channels, c, chan_list) {
00491          ast_softhangup(c, AST_SOFTHANGUP_SHUTDOWN);
00492       }
00493       AST_RWLIST_UNLOCK(&channels);
00494    }
00495 }

int ast_best_codec ( int  fmts  ) 

Pick the best audio codec.

Pick the best codec

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

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

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

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

G.726 is standard ADPCM, in RFC3551 packing order

G.726 is standard ADPCM, in AAL2 packing order

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

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

iLBC is not too bad

Speex is free, but computationally more expensive than GSM

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

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

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

Definition at line 712 of file channel.c.

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

Referenced by __oh323_new(), agent_call(), ast_codec_choose(), ast_iax2_new(), ast_speech_new(), builtin_atxfer(), echo_exec(), findmeexec(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), jingle_new(), local_new(), login_exec(), mgcp_new(), sip_new(), skinny_new(), skinny_set_rtp_peer(), socket_process(), start_rtp(), transmit_connect(), and unistim_new().

00713 {
00714    /* This just our opinion, expressed in code.  We are asked to choose
00715       the best codec to use, given no information */
00716    int x;
00717    static const int prefs[] =
00718    {
00719       /*! Okay, ulaw is used by all telephony equipment, so start with it */
00720       AST_FORMAT_ULAW,
00721       /*! Unless of course, you're a silly European, so then prefer ALAW */
00722       AST_FORMAT_ALAW,
00723       /*! G.722 is better then all below, but not as common as the above... so give ulaw and alaw priority */
00724       AST_FORMAT_G722,
00725       /*! Okay, well, signed linear is easy to translate into other stuff */
00726       AST_FORMAT_SLINEAR16,
00727       AST_FORMAT_SLINEAR,
00728       /*! G.726 is standard ADPCM, in RFC3551 packing order */
00729       AST_FORMAT_G726,
00730       /*! G.726 is standard ADPCM, in AAL2 packing order */
00731       AST_FORMAT_G726_AAL2,
00732       /*! ADPCM has great sound quality and is still pretty easy to translate */
00733       AST_FORMAT_ADPCM,
00734       /*! Okay, we're down to vocoders now, so pick GSM because it's small and easier to
00735           translate and sounds pretty good */
00736       AST_FORMAT_GSM,
00737       /*! iLBC is not too bad */
00738       AST_FORMAT_ILBC,
00739       /*! Speex is free, but computationally more expensive than GSM */
00740       AST_FORMAT_SPEEX,
00741       /*! Ick, LPC10 sounds terrible, but at least we have code for it, if you're tacky enough
00742           to use it */
00743       AST_FORMAT_LPC10,
00744       /*! G.729a is faster than 723 and slightly less expensive */
00745       AST_FORMAT_G729A,
00746       /*! Down to G.723.1 which is proprietary but at least designed for voice */
00747       AST_FORMAT_G723_1,
00748    };
00749 
00750    /* Strip out video */
00751    fmts &= AST_FORMAT_AUDIO_MASK;
00752    
00753    /* Find the first preferred codec in the format given */
00754    for (x = 0; x < ARRAY_LEN(prefs); x++) {
00755       if (fmts & prefs[x])
00756          return prefs[x];
00757    }
00758 
00759    ast_log(LOG_WARNING, "Don't know any of 0x%x formats\n", fmts);
00760 
00761    return 0;
00762 }

struct ast_channel* ast_bridged_channel ( struct ast_channel chan  )  [read]
int ast_call ( struct ast_channel chan,
char *  addr,
int  timeout 
)

Make a call.

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

Definition at line 4014 of file channel.c.

References AST_CDR_FLAG_DIALED, AST_CDR_FLAG_ORIGINATED, 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, ast_channel::cdr, and ast_channel::tech.

Referenced by __ast_request_and_dial(), agent_call(), ast_call_forward(), ast_feature_request_and_dial(), attempt_reconnect(), begin_dial_channel(), connect_link(), dial_exec_full(), do_forward(), do_idle_thread(), findmeexec(), ring_entry(), rpt(), rpt_exec(), and wait_for_answer().

04015 {
04016    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
04017       If the remote end does not answer within the timeout, then do NOT hang up, but
04018       return anyway.  */
04019    int res = -1;
04020    /* Stop if we're a zombie or need a soft hangup */
04021    ast_channel_lock(chan);
04022    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
04023       if (chan->cdr) {
04024          ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED);
04025          ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
04026       }
04027       if (chan->tech->call)
04028          res = chan->tech->call(chan, addr, timeout);
04029       ast_set_flag(chan, AST_FLAG_OUTGOING);
04030    }
04031    ast_channel_unlock(chan);
04032    return res;
04033 }

struct ast_channel* ast_call_forward ( struct ast_channel caller,
struct ast_channel orig,
int *  timeout,
int  format,
struct outgoing_helper oh,
int *  outstate 
) [read]

Forwards a call to a new channel specified by the original channel's call_forward str. If possible, the new forwarded channel is created and returned while the original one is terminated.

Parameters:
caller in channel that requested orig
orig channel being replaced by the call forward channel
timeout maximum amount of time to wait for setup of new forward channel
format requested channel format
oh outgoing helper used with original channel
outstate reason why unsuccessful (if uncuccessful)
Returns:
Returns the forwarded call's ast_channel on success or NULL on failure

Definition at line 3751 of file channel.c.

References outgoing_helper::account, accountcode, ast_call(), AST_CDR_FLAG_ORIGINATED, ast_cdr_setaccount(), ast_channel_datastore_inherit(), ast_channel_inherit_variables(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_copy_flags, ast_copy_string(), ast_hangup(), ast_log(), ast_request(), ast_set_callerid(), ast_set_variables(), ast_string_field_set, ast_strlen_zero(), ast_channel::cdr, CHANNEL_DEADLOCK_AVOIDANCE, ast_channel::cid, ast_callerid::cid_name, outgoing_helper::cid_name, ast_callerid::cid_num, outgoing_helper::cid_num, ast_channel::context, handle_cause(), LOG_NOTICE, outgoing_helper::parent_channel, pbx_builtin_getvar_helper(), S_OR, type, and outgoing_helper::vars.

Referenced by __ast_request_and_dial(), and ast_feature_request_and_dial().

03752 {
03753    char tmpchan[256];
03754    struct ast_channel *new = NULL;
03755    char *data, *type;
03756    int cause = 0;
03757 
03758    /* gather data and request the new forward channel */
03759    ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan));
03760    if ((data = strchr(tmpchan, '/'))) {
03761       *data++ = '\0';
03762       type = tmpchan;
03763    } else {
03764       const char *forward_context;
03765       ast_channel_lock(orig);
03766       forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT");
03767       snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context));
03768       ast_channel_unlock(orig);
03769       data = tmpchan;
03770       type = "Local";
03771    }
03772    if (!(new = ast_request(type, format, data, &cause))) {
03773       ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
03774       handle_cause(cause, outstate);
03775       ast_hangup(orig);
03776       return NULL;
03777    }
03778 
03779    /* Copy/inherit important information into new channel */
03780    if (oh) {
03781       if (oh->vars) {
03782          ast_set_variables(new, oh->vars);
03783       }
03784       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
03785          ast_set_callerid(new, oh->cid_num, oh->cid_name, oh->cid_num);
03786       }
03787       if (oh->parent_channel) {
03788          ast_channel_inherit_variables(oh->parent_channel, new);
03789          ast_channel_datastore_inherit(oh->parent_channel, new);
03790       }
03791       if (oh->account) {
03792          ast_cdr_setaccount(new, oh->account);
03793       }
03794    } else if (caller) { /* no outgoing helper so use caller if avaliable */
03795       ast_channel_inherit_variables(caller, new);
03796       ast_channel_datastore_inherit(caller, new);
03797    }
03798 
03799    ast_channel_lock(orig);
03800    while (ast_channel_trylock(new)) {
03801       CHANNEL_DEADLOCK_AVOIDANCE(orig);
03802    }
03803    ast_copy_flags(new->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED);
03804    ast_string_field_set(new, accountcode, orig->accountcode);
03805    if (!ast_strlen_zero(orig->cid.cid_num) && !ast_strlen_zero(new->cid.cid_name)) {
03806       ast_set_callerid(new, orig->cid.cid_num, orig->cid.cid_name, orig->cid.cid_num);
03807    }
03808    ast_channel_unlock(new);
03809    ast_channel_unlock(orig);
03810 
03811    /* call new channel */
03812    if ((*timeout = ast_call(new, data, 0))) {
03813       ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data);
03814       ast_hangup(orig);
03815       ast_hangup(new);
03816       return NULL;
03817    }
03818    ast_hangup(orig);
03819 
03820    return new;
03821 }

void ast_cancel_shutdown ( void   ) 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 510 of file channel.c.

Referenced by handle_abort_shutdown().

00511 {
00512    shutting_down = 0;
00513 }

const char* ast_cause2str ( int  state  ) 

Gives the string form of a given hangup cause.

Gives the string form of a given cause code

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

Definition at line 630 of file channel.c.

References ARRAY_LEN, causes, and ast_cause::desc.

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

00631 {
00632    int x;
00633 
00634    for (x = 0; x < ARRAY_LEN(causes); x++) {
00635       if (causes[x].cause == cause)
00636          return causes[x].desc;
00637    }
00638 
00639    return "Unknown";
00640 }

void ast_change_name ( struct ast_channel chan,
char *  newname 
)

Change channel name.

Note:
The channel must be locked before calling this function.

Definition at line 4268 of file channel.c.

References ast_string_field_set, EVENT_FLAG_CALL, manager_event, and name.

Referenced by update_name().

04269 {
04270    manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
04271    ast_string_field_set(chan, name, newname);
04272 }

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

Definition at line 5848 of file channel.c.

References __ast_channel_alloc_ap().

05852 {
05853    va_list ap1, ap2;
05854    struct ast_channel *result;
05855 
05856 
05857    va_start(ap1, name_fmt);
05858    va_start(ap2, name_fmt);
05859    result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
05860                amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2);
05861    va_end(ap1);
05862    va_end(ap2);
05863 
05864    return result;
05865 }

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

References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_RETRY, ast_channel_make_compatible(), ast_check_hangup(), ast_check_hangup_locked(), ast_clear_flag, AST_CONTROL_SRCUPDATE, ast_debug, AST_FEATURE_PLAY_WARNING, AST_FEATURE_WARNING_ACTIVE, AST_FLAG_END_DTMF_ONLY, AST_FLAG_NBRIDGE, AST_FLAG_ZOMBIE, ast_generic_bridge(), ast_indicate(), ast_log(), ast_samp2tv(), ast_set_flag, AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), ast_verb, ast_channel::audiohooks, ast_channel_tech::bridge, bridge_play_sounds(), bridge_playfile(), ast_channel::cid, ast_callerid::cid_num, ast_bridge_config::end_sound, EVENT_FLAG_CALL, ast_bridge_config::feature_timer, ast_bridge_config::features_callee, ast_bridge_config::features_caller, ast_bridge_config::firstpass, ast_bridge_config::flags, ast_channel::generator, LOG_WARNING, manager_bridge_event(), manager_event, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::nativeformats, ast_bridge_config::nexteventts, ast_bridge_config::play_warning, ast_channel::readformat, ast_channel_tech::send_digit_begin, ast_bridge_config::start_sound, ast_bridge_config::start_time, ast_channel::tech, ast_bridge_config::timelimit, update_bridge_vars(), ast_bridge_config::warning_freq, ast_bridge_config::warning_sound, and ast_channel::writeformat.

Referenced by ast_bridge_call().

05029 {
05030    struct ast_channel *who = NULL;
05031    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
05032    int nativefailed=0;
05033    int firstpass;
05034    int o0nativeformats;
05035    int o1nativeformats;
05036    long time_left_ms=0;
05037    char caller_warning = 0;
05038    char callee_warning = 0;
05039 
05040    if (c0->_bridge) {
05041       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
05042          c0->name, c0->_bridge->name);
05043       return -1;
05044    }
05045    if (c1->_bridge) {
05046       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
05047          c1->name, c1->_bridge->name);
05048       return -1;
05049    }
05050    
05051    /* Stop if we're a zombie or need a soft hangup */
05052    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
05053        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
05054       return -1;
05055 
05056    *fo = NULL;
05057    firstpass = config->firstpass;
05058    config->firstpass = 0;
05059 
05060    if (ast_tvzero(config->start_time))
05061       config->start_time = ast_tvnow();
05062    time_left_ms = config->timelimit;
05063 
05064    caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
05065    callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
05066 
05067    if (config->start_sound && firstpass) {
05068       if (caller_warning)
05069          bridge_playfile(c0, c1, config->start_sound, time_left_ms / 1000);
05070       if (callee_warning)
05071          bridge_playfile(c1, c0, config->start_sound, time_left_ms / 1000);
05072    }
05073 
05074    /* Keep track of bridge */
05075    c0->_bridge = c1;
05076    c1->_bridge = c0;
05077 
05078 
05079    o0nativeformats = c0->nativeformats;
05080    o1nativeformats = c1->nativeformats;
05081 
05082    if (config->feature_timer && !ast_tvzero(config->nexteventts)) {
05083       config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->feature_timer, 1000));
05084    } else if (config->timelimit && firstpass) {
05085       config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
05086       if (caller_warning || callee_warning)
05087          config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(config->play_warning, 1000));
05088    }
05089 
05090    if (!c0->tech->send_digit_begin)
05091       ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
05092    if (!c1->tech->send_digit_begin)
05093       ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
05094    manager_bridge_event(1, 1, c0, c1);
05095 
05096    /* Before we enter in and bridge these two together tell them both the source of audio has changed */
05097    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
05098    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
05099 
05100    for (/* ever */;;) {
05101       struct timeval now = { 0, };
05102       int to;
05103 
05104       to = -1;
05105 
05106       if (!ast_tvzero(config->nexteventts)) {
05107          now = ast_tvnow();
05108          to = ast_tvdiff_ms(config->nexteventts, now);
05109          if (to <= 0) {
05110             if (!config->timelimit) {
05111                res = AST_BRIDGE_COMPLETE;
05112                break;
05113             }
05114             to = 0;
05115          }
05116       }
05117 
05118       if (config->timelimit) {
05119          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
05120          if (time_left_ms < to)
05121             to = time_left_ms;
05122 
05123          if (time_left_ms <= 0) {
05124             if (caller_warning && config->end_sound)
05125                bridge_playfile(c0, c1, config->end_sound, 0);
05126             if (callee_warning && config->end_sound)
05127                bridge_playfile(c1, c0, config->end_sound, 0);
05128             *fo = NULL;
05129             if (who)
05130                *rc = who;
05131             res = 0;
05132             break;
05133          }
05134 
05135          if (!to) {
05136             if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
05137                int t = (time_left_ms + 500) / 1000; /* round to nearest second */
05138                if (caller_warning)
05139                   bridge_playfile(c0, c1, config->warning_sound, t);
05140                if (callee_warning)
05141                   bridge_playfile(c1, c0, config->warning_sound, t);
05142             }
05143             if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000)))
05144                config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
05145             else
05146                config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
05147          }
05148          ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
05149       }
05150 
05151       if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
05152          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
05153             c0->_softhangup = 0;
05154          if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
05155             c1->_softhangup = 0;
05156          c0->_bridge = c1;
05157          c1->_bridge = c0;
05158          ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
05159          continue;
05160       }
05161 
05162       /* Stop if we're a zombie or need a soft hangup */
05163       if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
05164           ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
05165          *fo = NULL;
05166          if (who)
05167             *rc = who;
05168          res = 0;
05169          ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
05170             c0->name, c1->name,
05171             ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
05172             ast_check_hangup(c0) ? "Yes" : "No",
05173             ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
05174             ast_check_hangup(c1) ? "Yes" : "No");
05175          break;
05176       }
05177 
05178       update_bridge_vars(c0, c1);
05179 
05180       bridge_play_sounds(c0, c1);
05181 
05182       if (c0->tech->bridge &&
05183           (c0->tech->bridge == c1->tech->bridge) &&
05184           !nativefailed && !c0->monitor && !c1->monitor &&
05185           !c0->audiohooks && !c1->audiohooks && 
05186           !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
05187          /* Looks like they share a bridge method and nothing else is in the way */
05188          ast_set_flag(c0, AST_FLAG_NBRIDGE);
05189          ast_set_flag(c1, AST_FLAG_NBRIDGE);
05190          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
05191             /* \todo  XXX here should check that cid_num is not NULL */
05192             manager_event(EVENT_FLAG_CALL, "Unlink",
05193                      "Channel1: %s\r\n"
05194                      "Channel2: %s\r\n"
05195                      "Uniqueid1: %s\r\n"
05196                      "Uniqueid2: %s\r\n"
05197                      "CallerID1: %s\r\n"
05198                      "CallerID2: %s\r\n",
05199                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
05200             ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
05201 
05202             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
05203             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
05204 
05205             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
05206                continue;
05207 
05208             c0->_bridge = NULL;
05209             c1->_bridge = NULL;
05210 
05211             return res;
05212          } else {
05213             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
05214             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
05215          }
05216          switch (res) {
05217          case AST_BRIDGE_RETRY:
05218             if (config->play_warning) {
05219                ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
05220             }
05221             continue;
05222          default:
05223             ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name);
05224             /* fallthrough */
05225          case AST_BRIDGE_FAILED_NOWARN:
05226             nativefailed++;
05227             break;
05228          }
05229       }
05230 
05231       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
05232           (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
05233           !(c0->generator || c1->generator)) {
05234          if (ast_channel_make_compatible(c0, c1)) {
05235             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
05236             manager_bridge_event(0, 1, c0, c1);
05237             return AST_BRIDGE_FAILED;
05238          }
05239          o0nativeformats = c0->nativeformats;
05240          o1nativeformats = c1->nativeformats;
05241       }
05242 
05243       update_bridge_vars(c0, c1);
05244 
05245       res = ast_generic_bridge(c0, c1, config, fo, rc, config->nexteventts);
05246       if (res != AST_BRIDGE_RETRY) {
05247          break;
05248       } else if (config->feature_timer) {
05249          /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */
05250          break;
05251       }
05252    }
05253 
05254    ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
05255    ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
05256 
05257    /* Now that we have broken the bridge the source will change yet again */
05258    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
05259    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
05260 
05261    c0->_bridge = NULL;
05262    c1->_bridge = NULL;
05263 
05264    /* \todo  XXX here should check that cid_num is not NULL */
05265    manager_event(EVENT_FLAG_CALL, "Unlink",
05266             "Channel1: %s\r\n"
05267             "Channel2: %s\r\n"
05268             "Uniqueid1: %s\r\n"
05269             "Uniqueid2: %s\r\n"
05270             "CallerID1: %s\r\n"
05271             "CallerID2: %s\r\n",
05272             c0->name, c1->name, c0->uniqueid, c1->uniqueid, c0->cid.cid_num, c1->cid.cid_num);
05273    ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
05274 
05275    return res;
05276 }

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.
See also:
ast_channel_cmpwhentohangup_tv()
Version:
1.6.1 deprecated function (only had seconds precision)

Definition at line 551 of file channel.c.

References ast_channel_cmpwhentohangup_tv().

00552 {
00553    struct timeval when = { offset, };
00554    return ast_channel_cmpwhentohangup_tv(chan, when);
00555 }

int ast_channel_cmpwhentohangup_tv ( struct ast_channel chan,
struct timeval  offset 
)

Compare a offset with when to hangup channel.

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

Definition at line 536 of file channel.c.

References ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and ast_channel::whentohangup.

Referenced by ast_channel_cmpwhentohangup().

00537 {
00538    struct timeval whentohangup;
00539 
00540    if (ast_tvzero(chan->whentohangup))
00541       return ast_tvzero(offset) ? 0 : -1;
00542 
00543    if (ast_tvzero(offset))
00544       return 1;
00545 
00546    whentohangup = ast_tvadd(offset, ast_tvnow());
00547 
00548    return ast_tvdiff_ms(whentohangup, chan->whentohangup);
00549 }

int ast_channel_datastore_add ( struct ast_channel chan,
struct ast_datastore datastore 
)

Add a datastore to a channel.

Note:
The channel should be locked before calling this function.
Return values:
0 success
non-zero failure

Definition at line 1507 of file channel.c.

References AST_LIST_INSERT_HEAD.

Referenced by _macro_exec(), acf_iaxvar_write(), acf_odbc_read(), add_features_datastores(), add_to_agi(), ast_iax2_new(), audiohook_volume_get(), authenticate_reply(), dial_exec_full(), dundi_query_read(), enable_jack_hook(), enum_query_read(), get_lock(), gosub_exec(), lua_get_state(), pbx_builtin_raise_exception(), setup_chanspy_ds(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process(), speech_create(), speex_write(), try_calling(), and volume_write().

01508 {
01509    int res = 0;
01510 
01511    AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry);
01512 
01513    return res;
01514 }

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

Create a channel data store object.

Note:
None of the datastore API calls lock the ast_channel they are using. So, the channel should be locked before calling the functions that take a channel argument.
Deprecated:
You should use the ast_datastore_alloc() generic function instead.
Version:
1.6.1 deprecated

Definition at line 1480 of file channel.c.

References ast_datastore_alloc.

01481 {
01482    return ast_datastore_alloc(info, uid);
01483 }

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

Find a datastore on a channel.

Note:
The channel should be locked before calling this function.
The datastore returned from this function must not be used if the reference to the channel is released.
Return values:
pointer to the datastore if found
NULL if not found

Definition at line 1521 of file channel.c.

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

Referenced by _macro_exec(), acf_exception_read(), acf_fetch(), acf_iaxvar_read(), acf_iaxvar_write(), add_agi_cmd(), add_features_datastores(), add_to_agi(), attended_transfer_occurred(), audiohook_volume_callback(), audiohook_volume_get(), builtin_atxfer(), chanspy_ds_free(), dial_exec_full(), disable_jack_hook(), dundi_result_read(), enable_jack_hook(), enum_result_read(), exec_odbcfinish(), find_speech(), func_inheritance_write(), get_agi_cmd(), get_lock(), gosub_exec(), handle_gosub(), iax2_call(), jack_hook_callback(), local_read(), local_write(), lock_fixup(), lua_get_state(), manage_parkinglot(), park_exec_full(), pbx_builtin_raise_exception(), pop_exec(), queue_transfer_fixup(), return_exec(), shared_read(), shared_write(), smdi_msg_read(), speech_background(), speech_destroy(), speex_callback(), speex_read(), speex_write(), stop_mixmonitor_exec(), try_calling(), unlock_read(), volume_callback(), and volume_write().

01522 {
01523    struct ast_datastore *datastore = NULL;
01524    
01525    if (info == NULL)
01526       return NULL;
01527 
01528    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
01529       if (datastore->info != info) {
01530          continue;
01531       }
01532 
01533       if (uid == NULL) {
01534          /* matched by type only */
01535          break;
01536       }
01537 
01538       if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
01539          /* Matched by type AND uid */
01540          break;
01541       }
01542    }
01543    AST_LIST_TRAVERSE_SAFE_END;
01544 
01545    return datastore;
01546 }

int ast_channel_datastore_free ( struct ast_datastore datastore  ) 

Free a channel data store object.

Deprecated:
You should use the ast_datastore_free() generic function instead.
Version:
1.6.1 deprecated

Definition at line 1485 of file channel.c.

References ast_datastore_free().

01486 {
01487    return ast_datastore_free(datastore);
01488 }

int ast_channel_datastore_inherit ( struct ast_channel from,
struct ast_channel to 
)

Inherit datastores from a parent to a child.

Definition at line 1490 of file channel.c.

References ast_datastore_alloc, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_datastore::data, DATASTORE_INHERIT_FOREVER, ast_datastore_info::duplicate, ast_datastore::info, ast_datastore::inheritance, and ast_datastore::uid.

Referenced by __ast_request_and_dial(), ast_call_forward(), dial_exec_full(), do_forward(), findmeexec(), local_call(), ring_entry(), and wait_for_answer().

01491 {
01492    struct ast_datastore *datastore = NULL, *datastore2;
01493 
01494    AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
01495       if (datastore->inheritance > 0) {
01496          datastore2 = ast_datastore_alloc(datastore->info, datastore->uid);
01497          if (datastore2) {
01498             datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL;
01499             datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
01500             AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
01501          }
01502       }
01503    }
01504    return 0;
01505 }

int ast_channel_datastore_remove ( struct ast_channel chan,
struct ast_datastore datastore 
)

Remove a datastore from a channel.

Note:
The channel should be locked before calling this function.
Return values:
0 success
non-zero failure

Definition at line 1516 of file channel.c.

References AST_LIST_REMOVE.

Referenced by acf_fetch(), chanspy_ds_free(), dial_exec_full(), disable_jack_hook(), exec_odbcfinish(), lua_get_state(), queue_transfer_fixup(), speech_background(), speech_destroy(), speex_write(), stop_mixmonitor_exec(), and try_calling().

01517 {
01518    return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1;
01519 }

int ast_channel_defer_dtmf ( struct ast_channel chan  ) 

Set defer DTMF flag on channel.

Defers DTMF

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

Definition at line 1141 of file channel.c.

References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.

Referenced by __adsi_transmit_messages(), and find_cache().

01142 {
01143    int pre = 0;
01144 
01145    if (chan) {
01146       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
01147       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
01148    }
01149    return pre;
01150 }

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

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

Referenced by dial_exec_full(), and wait_for_answer().

04930 {
04931    /* Make sure we can early bridge, if not error out */
04932    if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge)))
04933       return -1;
04934 
04935    return c0->tech->early_bridge(c0, c1);
04936 }

void ast_channel_free ( struct ast_channel chan  ) 

Free a channel structure.

Definition at line 1365 of file channel.c.

References ast_channel::alertpipe, ast_app_group_discard(), ast_cdr_discard(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_unlock, ast_copy_string(), ast_datastore_free(), ast_debug, AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), AST_FLAG_IN_CHANNEL_LIST, ast_free, ast_frfree, ast_jb_destroy(), AST_LIST_REMOVE_HEAD, ast_log(), AST_MAX_FDS, ast_moh_cleanup(), ast_mutex_destroy(), AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_string_field_free_memory, ast_test_flag, ast_timer_close(), ast_translator_free_path(), ast_var_delete(), ast_channel::cdr, channels, ast_channel::cid, f, free, free_cid(), ast_channel::lock_dont_use, 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::timer, ast_channel::varshead, and ast_channel::writetrans.

Referenced by acf_odbc_read(), acf_odbc_write(), action_getvar(), agent_cleanup(), agent_new(), ast_do_masquerade(), ast_hangup(), ast_iax2_new(), ast_pbx_outgoing_cdr_failed(), gtalk_newcall(), local_new(), make_email_file(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), and sendpage().

01366 {
01367    int fd;
01368 #ifdef HAVE_EPOLL
01369    int i;
01370 #endif
01371    struct ast_var_t *vardata;
01372    struct ast_frame *f;
01373    struct varshead *headp;
01374    struct ast_datastore *datastore = NULL;
01375    char name[AST_CHANNEL_NAME], *dashptr;
01376    int inlist;
01377    
01378    headp=&chan->varshead;
01379    
01380    inlist = ast_test_flag(chan, AST_FLAG_IN_CHANNEL_LIST);
01381    if (inlist) {
01382       AST_RWLIST_WRLOCK(&channels);
01383       if (!AST_RWLIST_REMOVE(&channels, chan, chan_list)) {
01384          ast_debug(1, "Unable to find channel in list to free. Assuming it has already been done.\n");
01385       }
01386       /* Lock and unlock the channel just to be sure nobody has it locked still
01387          due to a reference retrieved from the channel list. */
01388       ast_channel_lock(chan);
01389       ast_channel_unlock(chan);
01390    }
01391 
01392    /* Get rid of each of the data stores on the channel */
01393    ast_channel_lock(chan);
01394    while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
01395       /* Free the data store */
01396       ast_datastore_free(datastore);
01397    ast_channel_unlock(chan);
01398 
01399    /* Lock and unlock the channel just to be sure nobody has it locked still
01400       due to a reference that was stored in a datastore. (i.e. app_chanspy) */
01401    ast_channel_lock(chan);
01402    ast_channel_unlock(chan);
01403 
01404    if (chan->tech_pvt) {
01405       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
01406       ast_free(chan->tech_pvt);
01407    }
01408 
01409    if (chan->sched)
01410       sched_context_destroy(chan->sched);
01411 
01412    ast_copy_string(name, chan->name, sizeof(name));
01413    if ((dashptr = strrchr(name, '-'))) {
01414       *dashptr = '\0';
01415    }
01416 
01417    /* Stop monitoring */
01418    if (chan->monitor)
01419       chan->monitor->stop( chan, 0 );
01420 
01421    /* If there is native format music-on-hold state, free it */
01422    if (chan->music_state)
01423       ast_moh_cleanup(chan);
01424 
01425    /* Free translators */
01426    if (chan->readtrans)
01427       ast_translator_free_path(chan->readtrans);
01428    if (chan->writetrans)
01429       ast_translator_free_path(chan->writetrans);
01430    if (chan->pbx)
01431       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
01432    free_cid(&chan->cid);
01433    /* Close pipes if appropriate */
01434    if ((fd = chan->alertpipe[0]) > -1)
01435       close(fd);
01436    if ((fd = chan->alertpipe[1]) > -1)
01437       close(fd);
01438    if (chan->timer) {
01439       ast_timer_close(chan->timer);
01440    }
01441 #ifdef HAVE_EPOLL
01442    for (i = 0; i < AST_MAX_FDS; i++) {
01443       if (chan->epfd_data[i])
01444          free(chan->epfd_data[i]);
01445    }
01446    close(chan->epfd);
01447 #endif
01448    while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
01449       ast_frfree(f);
01450    
01451    /* loop over the variables list, freeing all data and deleting list items */
01452    /* no need to lock the list, as the channel is already locked */
01453    
01454    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
01455       ast_var_delete(vardata);
01456 
01457    ast_app_group_discard(chan);
01458 
01459    /* Destroy the jitterbuffer */
01460    ast_jb_destroy(chan);
01461 
01462    if (chan->cdr) {
01463       ast_cdr_discard(chan->cdr);
01464       chan->cdr = NULL;
01465    }
01466    
01467    ast_mutex_destroy(&chan->lock_dont_use);
01468 
01469    ast_string_field_free_memory(chan);
01470    ast_free(chan);
01471    if (inlist)
01472       AST_RWLIST_UNLOCK(&channels);
01473 
01474    /* Queue an unknown state, because, while we know that this particular
01475     * instance is dead, we don't know the state of all other possible
01476     * instances. */
01477    ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
01478 }

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

References ast_debug, AST_LIST_INSERT_TAIL, AST_LIST_TRAVERSE, ast_var_assign(), ast_var_full_name(), ast_var_name(), ast_var_value(), and ast_channel::varshead.

Referenced by __ast_request_and_dial(), agent_call(), ast_call_forward(), ast_feature_request_and_dial(), begin_dial_channel(), dial_exec_full(), do_forward(), findmeexec(), ring_entry(), and wait_for_answer().

04275 {
04276    struct ast_var_t *current, *newvar;
04277    const char *varname;
04278 
04279    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
04280       int vartype = 0;
04281 
04282       varname = ast_var_full_name(current);
04283       if (!varname)
04284          continue;
04285 
04286       if (varname[0] == '_') {
04287          vartype = 1;
04288          if (varname[1] == '_')
04289             vartype = 2;
04290       }
04291 
04292       switch (vartype) {
04293       case 1:
04294          newvar = ast_var_assign(&varname[1], ast_var_value(current));
04295          if (newvar) {
04296             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
04297             ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
04298          }
04299          break;
04300       case 2:
04301          newvar = ast_var_assign(varname, ast_var_value(current));
04302          if (newvar) {
04303             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
04304             ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
04305          }
04306          break;
04307       default:
04308          ast_debug(1, "Not copying variable %s.\n", ast_var_name(current));
04309          break;
04310       }
04311    }
04312 }

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

References ast_channel_make_compatible_helper().

Referenced by action_bridge(), app_exec(), ast_channel_bridge(), bridge_exec(), check_compat(), dial_exec_full(), do_forward(), park_exec_full(), try_calling(), and wait_for_answer().

04173 {
04174    /* Some callers do not check return code, and we must try to set all call legs correctly */
04175    int rc = 0;
04176 
04177    /* Set up translation from the chan to the peer */
04178    rc = ast_channel_make_compatible_helper(chan, peer);
04179 
04180    if (rc < 0)
04181       return rc;
04182 
04183    /* Set up translation from the peer to the chan */
04184    rc = ast_channel_make_compatible_helper(peer, chan);
04185 
04186    return rc;
04187 }

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

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

Referenced by ast_channel_make_compatible().

04132 {
04133    int src;
04134    int dst;
04135 
04136    if (from->readformat == to->writeformat && from->writeformat == to->readformat) {
04137       /* Already compatible!  Moving on ... */
04138       return 0;
04139    }
04140 
04141    /* Set up translation from the 'from' channel to the 'to' channel */
04142    src = from->nativeformats;
04143    dst = to->nativeformats;
04144 
04145    /* If there's no audio in this call, don't bother with trying to find a translation path */
04146    if ((src & AST_FORMAT_AUDIO_MASK) == 0 || (dst & AST_FORMAT_AUDIO_MASK) == 0)
04147       return 0;
04148 
04149    if (ast_translator_best_choice(&dst, &src) < 0) {
04150       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", from->name, src, to->name, dst);
04151       return -1;
04152    }
04153 
04154    /* if the best path is not 'pass through', then
04155       transcoding is needed; if desired, force transcode path
04156       to use SLINEAR between channels, but only if there is
04157       no direct conversion available */
04158    if ((src != dst) && ast_opt_transcode_via_slin &&
04159        (ast_translate_path_steps(dst, src) != 1))
04160       dst = AST_FORMAT_SLINEAR;
04161    if (ast_set_read_format(from, dst) < 0) {
04162       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", from->name, dst);
04163       return -1;
04164    }
04165    if (ast_set_write_format(to, dst) < 0) {
04166       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", to->name, dst);
04167       return -1;
04168    }
04169    return 0;
04170 }

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.

Note:
Neither channel passed here needs to be locked before calling this function.

Definition at line 4189 of file channel.c.

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

Referenced by ast_async_goto(), ast_pickup_call(), attempt_transfer(), builtin_atxfer(), check_availability(), check_bridge(), check_goto_on_transfer(), do_bridge_masquerade(), handle_invite_replaces(), iax_park(), masq_park_call(), misdn_attempt_transfer(), pickup_do(), sip_park(), and skinny_transfer().

04190 {
04191    int res = -1;
04192    struct ast_channel *final_orig, *final_clone, *base;
04193 
04194 retrymasq:
04195    final_orig = original;
04196    final_clone = clonechan;
04197 
04198    ast_channel_lock(original);
04199    while (ast_channel_trylock(clonechan)) {
04200       ast_channel_unlock(original);
04201       usleep(1);
04202       ast_channel_lock(original);
04203    }
04204 
04205    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
04206       and if so, we don't really want to masquerade it, but its proxy */
04207    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
04208       final_orig = original->_bridge;
04209 
04210    if (clonechan->_bridge && (clonechan->_bridge != ast_bridged_channel(clonechan)) && (clonechan->_bridge->_bridge != clonechan))
04211       final_clone = clonechan->_bridge;
04212    
04213    if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) {
04214       final_clone = base;
04215    }
04216 
04217    if ((final_orig != original) || (final_clone != clonechan)) {
04218       /* Lots and lots of deadlock avoidance.  The main one we're competing with
04219        * is ast_write(), which locks channels recursively, when working with a
04220        * proxy channel. */
04221       if (ast_channel_trylock(final_orig)) {
04222          ast_channel_unlock(clonechan);
04223          ast_channel_unlock(original);
04224          goto retrymasq;
04225       }
04226       if (ast_channel_trylock(final_clone)) {
04227          ast_channel_unlock(final_orig);
04228          ast_channel_unlock(clonechan);
04229          ast_channel_unlock(original);
04230          goto retrymasq;
04231       }
04232       ast_channel_unlock(clonechan);
04233       ast_channel_unlock(original);
04234       original = final_orig;
04235       clonechan = final_clone;
04236    }
04237 
04238    if (original == clonechan) {
04239       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
04240       ast_channel_unlock(clonechan);
04241       ast_channel_unlock(original);
04242       return -1;
04243    }
04244 
04245    ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n",
04246       clonechan->name, original->name);
04247    if (original->masq) {
04248       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
04249          original->masq->name, original->name);
04250    } else if (clonechan->masqr) {
04251       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
04252          clonechan->name, clonechan->masqr->name);
04253    } else {
04254       original->masq = clonechan;
04255       clonechan->masqr = original;
04256       ast_queue_frame(original, &ast_null_frame);
04257       ast_queue_frame(clonechan, &ast_null_frame);
04258       ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", clonechan->name, original->name);
04259       res = 0;
04260    }
04261 
04262    ast_channel_unlock(clonechan);
04263    ast_channel_unlock(original);
04264 
04265    return res;
04266 }

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

Checks the value of an option

Query the value of an option Works similarly to setoption except only reads the options.

Definition at line 5292 of file channel.c.

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

Referenced by ast_channel_get_t38_state().

05293 {
05294    if (!chan->tech->queryoption) {
05295       errno = ENOSYS;
05296       return -1;
05297    }
05298 
05299    if (block)
05300       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
05301 
05302    return chan->tech->queryoption(chan, option, data, datalen);
05303 }

const char* ast_channel_reason2str ( int  reason  ) 

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

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

Definition at line 3715 of file channel.c.

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

Referenced by attempt_thread().

03716 {
03717    switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */
03718    {
03719    case 0:
03720       return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
03721    case AST_CONTROL_HANGUP:
03722       return "Hangup";
03723    case AST_CONTROL_RING:
03724       return "Local Ring";
03725    case AST_CONTROL_RINGING:
03726       return "Remote end Ringing";
03727    case AST_CONTROL_ANSWER:
03728       return "Remote end has Answered";
03729    case AST_CONTROL_BUSY:
03730       return "Remote end is Busy";
03731    case AST_CONTROL_CONGESTION:
03732       return "Congestion (circuits busy)";
03733    default:
03734       return "Unknown Reason!!";
03735    }
03736 }

int ast_channel_register ( const struct ast_channel_tech tech  ) 

Register a new telephony channel in Asterisk.

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

Definition at line 558 of file channel.c.

References ast_calloc, ast_debug, AST_LIST_INSERT_HEAD, AST_LIST_TRAVERSE, ast_log(), AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, channels, ast_channel_tech::description, LOG_WARNING, chanlist::tech, and ast_channel_tech::type.

Referenced by load_module(), and unload_module().

00559 {
00560    struct chanlist *chan;
00561 
00562    AST_RWLIST_WRLOCK(&channels);
00563 
00564    AST_LIST_TRAVERSE(&backends, chan, list) {
00565       if (!strcasecmp(tech->type, chan->tech->type)) {
00566          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00567          AST_RWLIST_UNLOCK(&channels);
00568          return -1;
00569       }
00570    }
00571    
00572    if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00573       AST_RWLIST_UNLOCK(&channels);
00574       return -1;
00575    }
00576    chan->tech = tech;
00577    AST_LIST_INSERT_HEAD(&backends, chan, list);
00578 
00579    ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00580 
00581    ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description);
00582 
00583    AST_RWLIST_UNLOCK(&channels);
00584    return 0;
00585 }

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

Sends HTML on given channel

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

Definition at line 4118 of file channel.c.

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

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

04119 {
04120    if (chan->tech->send_html)
04121       return chan->tech->send_html(chan, subclass, data, datalen);
04122    return -1;
04123 }

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

Sends a URL on a given link

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

Definition at line 4125 of file channel.c.

References ast_channel_sendhtml(), and AST_HTML_URL.

Referenced by dial_exec_full(), sendurl_exec(), and try_calling().

04126 {
04127    return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
04128 }

void ast_channel_set_fd ( struct ast_channel chan,
int  which,
int  fd 
)

Set the file descriptor on the channel

Definition at line 1549 of file channel.c.

References ast_calloc, ast_epoll_data::chan, ast_channel::fds, free, and ast_epoll_data::which.

Referenced by __ast_channel_alloc_ap(), __oh323_new(), __oh323_rtp_create(), __oh323_update_info(), alsa_new(), ast_deactivate_generator(), ast_do_masquerade(), dahdi_new(), gtalk_new(), jingle_new(), mgcp_new(), misdn_new(), nbs_new(), oss_new(), phone_new(), pri_assign_bearer(), pri_fixup_principle(), setformat(), sip_new(), skinny_new(), start_rtp(), and swap_subs().

01550 {
01551 #ifdef HAVE_EPOLL
01552    struct epoll_event ev;
01553    struct ast_epoll_data *aed = NULL;
01554 
01555    if (chan->fds[which] > -1) {
01556       epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev);
01557       aed = chan->epfd_data[which];
01558    }
01559 
01560    /* If this new fd is valid, add it to the epoll */
01561    if (fd > -1) {
01562       if (!aed && (!(aed = ast_calloc(1, sizeof(*aed)))))
01563          return;
01564       
01565       chan->epfd_data[which] = aed;
01566       aed->chan = chan;
01567       aed->which = which;
01568       
01569       ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
01570       ev.data.ptr = aed;
01571       epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev);
01572    } else if (aed) {
01573       /* We don't have to keep around this epoll data structure now */
01574       free(aed);
01575       chan->epfd_data[which] = NULL;
01576    }
01577 #endif
01578    chan->fds[which] = fd;
01579    return;
01580 }

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

Sets an option on a channel.

Sets an option on a channel

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

Definition at line 5279 of file channel.c.

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

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

05280 {
05281    if (!chan->tech->setoption) {
05282       errno = ENOSYS;
05283       return -1;
05284    }
05285 
05286    if (block)
05287       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
05288 
05289    return chan->tech->setoption(chan, option, data, datalen);
05290 }

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 relative to the current time of when to hang up

This function sets the absolute time out on a channel (when to hang up).

Note:
This function does not require that the channel is locked before calling it.
Returns:
Nothing
See also:
ast_channel_setwhentohangup_tv()
Version:
1.6.1 deprecated function (only had seconds precision)

Definition at line 529 of file channel.c.

References ast_channel_setwhentohangup_tv().

00530 {
00531    struct timeval when = { offset, };
00532    ast_channel_setwhentohangup_tv(chan, when);
00533 }

void ast_channel_setwhentohangup_tv ( struct ast_channel chan,
struct timeval  offset 
)

Set when to hangup channel.

Set when to hang a channel up.

Definition at line 522 of file channel.c.

References ast_null_frame, ast_queue_frame(), ast_tvadd(), ast_tvnow(), ast_tvzero(), and ast_channel::whentohangup.

Referenced by action_timeout(), ast_channel_setwhentohangup(), handle_autohangup(), and timeout_write().

00523 {
00524    chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow());
00525    ast_queue_frame(chan, &ast_null_frame);
00526    return;
00527 }

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

Starts a silence generator on the given channel.

Parameters:
chan The channel to generate silence on
Returns:
An ast_silence_generator pointer, or NULL if an error occurs

This function will cause SLINEAR silence to be generated on the supplied channel until it is disabled; if the channel cannot be put into SLINEAR mode then the function will fail.

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

Definition at line 5612 of file channel.c.

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

Referenced by __ast_play_and_record(), ast_dtmf_stream(), ast_safe_sleep_conditional(), channel_spy(), record_exec(), TransferCallStep1(), waitfor_exec(), and waitforring_exec().

05613 {
05614    struct ast_silence_generator *state;
05615 
05616    if (!(state = ast_calloc(1, sizeof(*state)))) {
05617       return NULL;
05618    }
05619 
05620    state->old_write_format = chan->writeformat;
05621 
05622    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
05623       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
05624       ast_free(state);
05625       return NULL;
05626    }
05627 
05628    ast_activate_generator(chan, &silence_generator, state);
05629 
05630    ast_debug(1, "Started silence generator on '%s'\n", chan->name);
05631 
05632    return state;
05633 }

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

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

Referenced by __ast_play_and_record(), ast_dtmf_stream(), ast_safe_sleep_conditional(), channel_spy(), HandleCallOutgoing(), key_dial_page(), record_exec(), unistim_hangup(), waitfor_exec(), and waitforring_exec().

05636 {
05637    if (!state)
05638       return;
05639 
05640    ast_deactivate_generator(chan);
05641 
05642    ast_debug(1, "Stopped silence generator on '%s'\n", chan->name);
05643 
05644    if (ast_set_write_format(chan, state->old_write_format) < 0)
05645       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
05646 
05647    ast_free(state);
05648 }

int ast_channel_supports_html ( struct ast_channel channel  ) 

Checks for HTML support on a channel

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

Definition at line 4113 of file channel.c.

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

Referenced by dial_exec_full(), sendurl_exec(), and try_calling().

04114 {
04115    return (chan->tech->send_html) ? 1 : 0;
04116 }

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

References ast_clear_flag, and AST_FLAG_DEFER_DTMF.

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

01154 {
01155    if (chan)
01156       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
01157 }

void ast_channel_unregister ( const struct ast_channel_tech tech  ) 

Unregister channel driver.

Unregister a channel technology.

Definition at line 588 of file channel.c.

References ast_debug, ast_free, AST_LIST_REMOVE_CURRENT, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, channels, chanlist::tech, and ast_channel_tech::type.

Referenced by __unload_module(), load_module(), and unload_module().

00589 {
00590    struct chanlist *chan;
00591 
00592    ast_debug(1, "Unregistering channel type '%s'\n", tech->type);
00593 
00594    AST_RWLIST_WRLOCK(&channels);
00595 
00596    AST_LIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00597       if (chan->tech == tech) {
00598          AST_LIST_REMOVE_CURRENT(list);
00599          ast_free(chan);
00600          ast_verb(2, "Unregistered channel type '%s'\n", tech->type);
00601          break;   
00602       }
00603    }
00604    AST_LIST_TRAVERSE_SAFE_END;
00605 
00606    AST_RWLIST_UNLOCK(&channels);
00607 }

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

Browse channels in use.

Browse channels in use Browse the channels currently in use.

Definition at line 1267 of file channel.c.

References channel_find_locked().

Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_pickup_call(), conf_exec(), func_channels_read(), handle_chanlist(), handle_core_set_debug_channel(), next_channel(), pickup_by_exten(), and pickup_by_mark().

01268 {
01269    return channel_find_locked(prev, NULL, 0, NULL, NULL);
01270 }

void ast_channels_init ( void   ) 

Provided by channel.c

Definition at line 5533 of file channel.c.

References ARRAY_LEN, ast_cli_register_multiple(), and cli_channel.

Referenced by main().

struct ast_variable* ast_channeltype_list ( void   )  [read]

return an ast_variable list of channeltypes

Definition at line 186 of file channel.c.

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

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

int ast_check_hangup ( struct ast_channel chan  ) 

Checks to see if a channel is needing hang up.

Check to see if a channel is needing hang up.

Definition at line 462 of file channel.c.

References ast_channel::_softhangup, AST_SOFTHANGUP_TIMEOUT, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and ast_channel::whentohangup.

Referenced by __ast_pbx_run(), __ast_read(), _macro_exec(), action_redirect(), agent_indicate(), agi_exec(), agi_handle_command(), announce_thread(), ast_bridge_call(), ast_bridge_call_thread(), ast_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_feature_request_and_dial(), ast_indicate_data(), ast_raw_answer(), ast_readstring_full(), ast_recvtext(), ast_rtp_bridge(), ast_sendtext(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), ast_write(), autoservice_run(), bridge_exec(), bridge_native_loop(), bridge_p2p_loop(), builtin_atxfer(), channel_spy(), check_bridge(), common_exec(), conf_play(), conf_run(), dahdi_sendtext(), dahdi_setoption(), dial_exec_full(), dundi_lookup_internal(), eagi_exec(), eivr_comm(), findmeexec(), handle_sendimage(), iax2_bridge(), launch_asyncagi(), lua_check_hangup(), ospfinished_exec(), pbx_builtin_incomplete(), pbx_exec(), read_exec(), readexten_exec(), rpt(), rpt_exec(), run_ras(), try_calling(), and wait_for_answer().

00463 {
00464    if (chan->_softhangup)     /* yes if soft hangup flag set */
00465       return 1;
00466    if (ast_tvzero(chan->whentohangup)) /* no if no hangup scheduled */
00467       return 0;
00468    if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0)  /* no if hangup time has not come yet. */
00469       return 0;
00470    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */
00471    return 1;
00472 }

static int ast_check_hangup_locked ( struct ast_channel chan  )  [static]

Definition at line 474 of file channel.c.

References ast_channel_lock, ast_channel_unlock, and ast_check_hangup().

Referenced by ast_channel_bridge().

00475 {
00476    int res;
00477    ast_channel_lock(chan);
00478    res = ast_check_hangup(chan);
00479    ast_channel_unlock(chan);
00480    return res;
00481 }

void ast_deactivate_generator ( struct ast_channel chan  ) 
int ast_do_masquerade ( struct ast_channel original  ) 

Masquerade a channel.

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

References ast_channel::_softhangup, ast_channel::_state, ast_channel::adsicpe, ast_channel::alertpipe, ast_app_group_update(), ast_cause2str(), ast_channel_free(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_set_fd(), ast_channel_unlock, ast_copy_string(), ast_debug, AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, AST_FLAG_OUTGOING, AST_FLAG_ZOMBIE, AST_GENERATOR_FD, ast_indicate(), AST_LIST_APPEND_LIST, AST_LIST_FIRST, AST_LIST_HEAD_NOLOCK, AST_LIST_HEAD_SET_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, AST_LIST_TRAVERSE_SAFE_BEGIN, AST_LIST_TRAVERSE_SAFE_END, ast_log(), AST_MAX_FDS, ast_null_frame, ast_queue_frame(), ast_set_flag, ast_set_read_format(), ast_set_write_format(), AST_SOFTHANGUP_DEV, ast_state2str(), ast_string_field_set, ast_test_flag, AST_TIMING_FD, ast_channel::blocker, ast_channel::cdr, ast_datastore_info::chan_fixup, ast_channel::cid, clone_variables(), ast_datastore::data, errno, EVENT_FLAG_CALL, ast_channel::fdno, ast_channel::fds, ast_channel_tech::fixup, free_translation(), ast_channel_tech::hangup, ast_channel::hangupcause, ast_datastore::info, language, ast_channel::lock_dont_use, LOG_WARNING, manager_event, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, musicclass, name, ast_channel::nativeformats, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, report_new_callerid(), ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel_tech::type, ast_channel::visible_indication, and ast_channel::writeformat.

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

04366 {
04367    int x,i;
04368    int res=0;
04369    int origstate;
04370    struct ast_frame *current;
04371    const struct ast_channel_tech *t;
04372    void *t_pvt;
04373    struct ast_callerid tmpcid;
04374    struct ast_channel *clonechan = original->masq;
04375    struct ast_cdr *cdr;
04376    int rformat = original->readformat;
04377    int wformat = original->writeformat;
04378    char newn[AST_CHANNEL_NAME];
04379    char orig[AST_CHANNEL_NAME];
04380    char masqn[AST_CHANNEL_NAME];
04381    char zombn[AST_CHANNEL_NAME];
04382 
04383    ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
04384       clonechan->name, clonechan->_state, original->name, original->_state);
04385 
04386    manager_event(EVENT_FLAG_CALL, "Masquerade", "Clone: %s\r\nCloneState: %s\r\nOriginal: %s\r\nOriginalState: %s\r\n",
04387             clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state));
04388 
04389    /* XXX This operation is a bit odd.  We're essentially putting the guts of
04390     * the clone channel into the original channel.  Start by killing off the
04391     * original channel's backend.  While the features are nice, which is the
04392     * reason we're keeping it, it's still awesomely weird. XXX */
04393 
04394    /* We need the clone's lock, too */
04395    ast_channel_lock(clonechan);
04396 
04397    ast_debug(2, "Got clone lock for masquerade on '%s' at %p\n", clonechan->name, &clonechan->lock_dont_use);
04398 
04399    /* Having remembered the original read/write formats, we turn off any translation on either
04400       one */
04401    free_translation(clonechan);
04402    free_translation(original);
04403 
04404 
04405    /* Unlink the masquerade */
04406    original->masq = NULL;
04407    clonechan->masqr = NULL;
04408    
04409    /* Save the original name */
04410    ast_copy_string(orig, original->name, sizeof(orig));
04411    /* Save the new name */
04412    ast_copy_string(newn, clonechan->name, sizeof(newn));
04413    /* Create the masq name */
04414    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
04415       
04416    /* Copy the name from the clone channel */
04417    ast_string_field_set(original, name, newn);
04418 
04419    /* Mangle the name of the clone channel */
04420    ast_string_field_set(clonechan, name, masqn);
04421    
04422    /* Notify any managers of the change, first the masq then the other */
04423    manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", newn, masqn, clonechan->uniqueid);
04424    manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", orig, newn, original->uniqueid);
04425 
04426    /* Swap the technologies */   
04427    t = original->tech;
04428    original->tech = clonechan->tech;
04429    clonechan->tech = t;
04430 
04431    /* Swap the cdrs */
04432    cdr = original->cdr;
04433    original->cdr = clonechan->cdr;
04434    clonechan->cdr = cdr;
04435 
04436    t_pvt = original->tech_pvt;
04437    original->tech_pvt = clonechan->tech_pvt;
04438    clonechan->tech_pvt = t_pvt;
04439 
04440    /* Swap the alertpipes */
04441    for (i = 0; i < 2; i++) {
04442       x = original->alertpipe[i];
04443       original->alertpipe[i] = clonechan->alertpipe[i];
04444       clonechan->alertpipe[i] = x;
04445    }
04446 
04447    /* 
04448     * Swap the readq's.  The end result should be this:
04449     *
04450     *  1) All frames should be on the new (original) channel.
04451     *  2) Any frames that were already on the new channel before this
04452     *     masquerade need to be at the end of the readq, after all of the
04453     *     frames on the old (clone) channel.
04454     *  3) The alertpipe needs to get poked for every frame that was already
04455     *     on the new channel, since we are now using the alert pipe from the
04456     *     old (clone) channel.
04457     */
04458    {
04459       AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
04460       AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
04461 
04462       AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
04463       AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list);
04464 
04465       while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
04466          AST_LIST_INSERT_TAIL(&original->readq, current, frame_list);
04467          if (original->alertpipe[1] > -1) {
04468             int poke = 0;
04469 
04470             if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) {
04471                ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
04472             }
04473          }
04474       }
04475    }
04476 
04477    /* Swap the raw formats */
04478    x = original->rawreadformat;
04479    original->rawreadformat = clonechan->rawreadformat;
04480    clonechan->rawreadformat = x;
04481    x = original->rawwriteformat;
04482    original->rawwriteformat = clonechan->rawwriteformat;
04483    clonechan->rawwriteformat = x;
04484 
04485    clonechan->_softhangup = AST_SOFTHANGUP_DEV;
04486 
04487    /* And of course, so does our current state.  Note we need not
04488       call ast_setstate since the event manager doesn't really consider
04489       these separate.  We do this early so that the clone has the proper
04490       state of the original channel. */
04491    origstate = original->_state;
04492    original->_state = clonechan->_state;
04493    clonechan->_state = origstate;
04494 
04495    if (clonechan->tech->fixup){
04496       res = clonechan->tech->fixup(original, clonechan);
04497       if (res)
04498          ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clonechan->name);
04499    }
04500 
04501    /* Start by disconnecting the original's physical side */
04502    if (clonechan->tech->hangup)
04503       res = clonechan->tech->hangup(clonechan);
04504    if (res) {
04505       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
04506       ast_channel_unlock(clonechan);
04507       return -1;
04508    }
04509 
04510    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig);
04511    /* Mangle the name of the clone channel */
04512    ast_string_field_set(clonechan, name, zombn);
04513    manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", masqn, zombn, clonechan->uniqueid);
04514 
04515    /* Update the type. */
04516    t_pvt = original->monitor;
04517    original->monitor = clonechan->monitor;
04518    clonechan->monitor = t_pvt;
04519 
04520    /* Keep the same language.  */
04521    ast_string_field_set(original, language, clonechan->language);
04522    /* Copy the FD's other than the generator fd */
04523    for (x = 0; x < AST_MAX_FDS; x++) {
04524       if (x != AST_GENERATOR_FD)
04525          ast_channel_set_fd(original, x, clonechan->fds[x]);
04526    }
04527 
04528    ast_app_group_update(clonechan, original);
04529 
04530    /* Move data stores over */
04531    if (AST_LIST_FIRST(&clonechan->datastores)) {
04532       struct ast_datastore *ds;
04533       /* We use a safe traversal here because some fixup routines actually
04534        * remove the datastore from the list and free them.
04535        */
04536       AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) {
04537          if (ds->info->chan_fixup)
04538             ds->info->chan_fixup(ds->data, clonechan, original);
04539       }
04540       AST_LIST_TRAVERSE_SAFE_END;
04541       AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry);
04542    }
04543 
04544    clone_variables(original, clonechan);
04545    /* Presense of ADSI capable CPE follows clone */
04546    original->adsicpe = clonechan->adsicpe;
04547    /* Bridge remains the same */
04548    /* CDR fields remain the same */
04549    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
04550    /* Application and data remain the same */
04551    /* Clone exception  becomes real one, as with fdno */
04552    ast_set_flag(original, ast_test_flag(clonechan, AST_FLAG_OUTGOING | AST_FLAG_EXCEPTION));
04553    original->fdno = clonechan->fdno;
04554    /* Schedule context remains the same */
04555    /* Stream stuff stays the same */
04556    /* Keep the original state.  The fixup code will need to work with it most likely */
04557 
04558    /* Just swap the whole structures, nevermind the allocations, they'll work themselves
04559       out. */
04560    tmpcid = original->cid;
04561    original->cid = clonechan->cid;
04562    clonechan->cid = tmpcid;
04563    report_new_callerid(original);
04564 
04565    /* Restore original timing file descriptor */
04566    ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd);
04567 
04568    /* Our native formats are different now */
04569    original->nativeformats = clonechan->nativeformats;
04570 
04571    /* Context, extension, priority, app data, jump table,  remain the same */
04572    /* pvt switches.  pbx stays the same, as does next */
04573 
04574    /* Set the write format */
04575    ast_set_write_format(original, wformat);
04576 
04577    /* Set the read format */
04578    ast_set_read_format(original, rformat);
04579 
04580    /* Copy the music class */
04581    ast_string_field_set(original, musicclass, clonechan->musicclass);
04582 
04583    ast_debug(1, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
04584 
04585    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
04586       can fix up everything as best as possible */
04587    if (original->tech->fixup) {
04588       res = original->tech->fixup(clonechan, original);
04589       if (res) {
04590          ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
04591             original->tech->type, original->name);
04592          ast_channel_unlock(clonechan);
04593          return -1;
04594       }
04595    } else
04596       ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
04597          original->tech->type, original->name);
04598 
04599    /* 
04600     * If an indication is currently playing, maintain it on the channel 
04601     * that is taking the place of original 
04602     *
04603     * This is needed because the masquerade is swapping out in the internals
04604     * of this channel, and the new channel private data needs to be made
04605     * aware of the current visible indication (RINGING, CONGESTION, etc.)
04606     */
04607    if (original->visible_indication) {
04608       ast_indicate(original, original->visible_indication);
04609    }
04610    
04611    /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
04612       a zombie so nothing tries to touch it.  If it's already been marked as a
04613       zombie, then free it now (since it already is considered invalid). */
04614    if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
04615       ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name);
04616       ast_channel_unlock(clonechan);
04617       manager_event(EVENT_FLAG_CALL, "Hangup",
04618          "Channel: %s\r\n"
04619          "Uniqueid: %s\r\n"
04620          "Cause: %d\r\n"
04621          "Cause-txt: %s\r\n",
04622          clonechan->name,
04623          clonechan->uniqueid,
04624          clonechan->hangupcause,
04625          ast_cause2str(clonechan->hangupcause)
04626          );
04627       ast_channel_free(clonechan);
04628    } else {
04629       ast_debug(1, "Released clone lock on '%s'\n", clonechan->name);
04630       ast_set_flag(clonechan, AST_FLAG_ZOMBIE);
04631       ast_queue_frame(clonechan, &ast_null_frame);
04632       ast_channel_unlock(clonechan);
04633    }
04634 
04635    /* Signal any blocker */
04636    if (ast_test_flag(original, AST_FLAG_BLOCKING))
04637       pthread_kill(original->blocker, SIGURG);
04638    ast_debug(1, "Done Masquerading %s (%d)\n", original->name, original->_state);
04639    return 0;
04640 }

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

Definition at line 4748 of file channel.c.

References ast_channel::_bridge, ast_channel::_softhangup, AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, AST_CONTROL_HOLD, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, ast_debug, AST_FEATURE_WARNING_ACTIVE, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_indicate_data(), ast_jb_do_usecheck(), ast_jb_empty_and_reset(), ast_jb_get_and_deliver(), ast_jb_get_when_to_wakeup(), ast_jb_put(), ast_poll_channel_add(), ast_poll_channel_del(), ast_read(), ast_samp2tv(), ast_set_flag, AST_SOFTHANGUP_UNBRIDGE, ast_tvadd(), ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), ast_waitfor_n(), ast_write(), ast_frame::data, ast_frame::datalen, f, ast_bridge_config::feature_timer, ast_bridge_config::flags, ast_frame::frametype, ast_channel::nativeformats, ast_bridge_config::nexteventts, ast_bridge_config::partialfeature_timer, ast_frame::ptr, ast_frame::subclass, ast_channel::tech_pvt, and ast_bridge_config::timelimit.

Referenced by ast_channel_bridge().

04751 {
04752    /* Copy voice back and forth between the two channels. */
04753    struct ast_channel *cs[3];
04754    struct ast_frame *f;
04755    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
04756    int o0nativeformats;
04757    int o1nativeformats;
04758    int watch_c0_dtmf;
04759    int watch_c1_dtmf;
04760    void *pvt0, *pvt1;
04761    /* Indicates whether a frame was queued into a jitterbuffer */
04762    int frame_put_in_jb = 0;
04763    int jb_in_use;
04764    int to;
04765    
04766    cs[0] = c0;
04767    cs[1] = c1;
04768    pvt0 = c0->tech_pvt;
04769    pvt1 = c1->tech_pvt;
04770    o0nativeformats = c0->nativeformats;
04771    o1nativeformats = c1->nativeformats;
04772    watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
04773    watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
04774 
04775    /* Check the need of a jitterbuffer for each channel */
04776    jb_in_use = ast_jb_do_usecheck(c0, c1);
04777    if (jb_in_use)
04778       ast_jb_empty_and_reset(c0, c1);
04779 
04780    ast_poll_channel_add(c0, c1);
04781 
04782    if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) {
04783       /* calculate when the bridge should possibly break
04784        * if a partial feature match timed out */
04785       config->partialfeature_timer = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000));
04786    } else {
04787       memset(&config->partialfeature_timer, 0, sizeof(config->partialfeature_timer));
04788    }
04789 
04790    for (;;) {
04791       struct ast_channel *who, *other;
04792 
04793       if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
04794           (o0nativeformats != c0->nativeformats) ||
04795           (o1nativeformats != c1->nativeformats)) {
04796          /* Check for Masquerade, codec changes, etc */
04797          res = AST_BRIDGE_RETRY;
04798          break;
04799       }
04800       if (bridge_end.tv_sec) {
04801          to = ast_tvdiff_ms(bridge_end, ast_tvnow());
04802          if (to <= 0) {
04803             if (config->timelimit) {
04804                res = AST_BRIDGE_RETRY;
04805                /* generic bridge ending to play warning */
04806                ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
04807             } else {
04808                res = AST_BRIDGE_COMPLETE;
04809             }
04810             break;
04811          }
04812       } else {
04813          /* If a feature has been started and the bridge is configured to 
04814           * to not break, leave the channel bridge when the feature timer
04815           * time has elapsed so the DTMF will be sent to the other side. 
04816           */
04817          if (!ast_tvzero(config->partialfeature_timer)) {
04818             int diff = ast_tvdiff_ms(config->partialfeature_timer, ast_tvnow());
04819             if (diff <= 0) {
04820                res = AST_BRIDGE_RETRY;
04821                break;
04822             }
04823          }
04824          to = -1;
04825       }
04826       /* Calculate the appropriate max sleep interval - in general, this is the time,
04827          left to the closest jb delivery moment */
04828       if (jb_in_use)
04829          to = ast_jb_get_when_to_wakeup(c0, c1, to);
04830       who = ast_waitfor_n(cs, 2, &to);
04831       if (!who) {
04832          /* No frame received within the specified timeout - check if we have to deliver now */
04833          if (jb_in_use)
04834             ast_jb_get_and_deliver(c0, c1);
04835          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
04836             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04837                c0->_softhangup = 0;
04838             if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
04839                c1->_softhangup = 0;
04840             c0->_bridge = c1;
04841             c1->_bridge = c0;
04842          }
04843          continue;
04844       }
04845       f = ast_read(who);
04846       if (!f) {
04847          *fo = NULL;
04848          *rc = who;
04849          ast_debug(1, "Didn't get a frame from channel: %s\n",who->name);
04850          break;
04851       }
04852 
04853       other = (who == c0) ? c1 : c0; /* the 'other' channel */
04854       /* Try add the frame info the who's bridged channel jitterbuff */
04855       if (jb_in_use)
04856          frame_put_in_jb = !ast_jb_put(other, f);
04857 
04858       if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
04859          int bridge_exit = 0;
04860 
04861          switch (f->subclass) {
04862          case AST_CONTROL_HOLD:
04863          case AST_CONTROL_UNHOLD:
04864          case AST_CONTROL_VIDUPDATE:
04865          case AST_CONTROL_SRCUPDATE:
04866          case AST_CONTROL_T38_PARAMETERS:
04867             ast_indicate_data(other, f->subclass, f->data.ptr, f->datalen);
04868             if (jb_in_use) {
04869                ast_jb_empty_and_reset(c0, c1);
04870             }
04871             break;
04872          default:
04873             *fo = f;
04874             *rc = who;
04875             bridge_exit = 1;
04876             ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
04877             break;
04878          }
04879          if (bridge_exit)
04880             break;
04881       }
04882       if ((f->frametype == AST_FRAME_VOICE) ||
04883           (f->frametype == AST_FRAME_DTMF_BEGIN) ||
04884           (f->frametype == AST_FRAME_DTMF) ||
04885           (f->frametype == AST_FRAME_VIDEO) ||
04886           (f->frametype == AST_FRAME_IMAGE) ||
04887           (f->frametype == AST_FRAME_HTML) ||
04888           (f->frametype == AST_FRAME_MODEM) ||
04889           (f->frametype == AST_FRAME_TEXT)) {
04890          /* monitored dtmf causes exit from bridge */
04891          int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
04892 
04893          if (monitored_source && 
04894             (f->frametype == AST_FRAME_DTMF_END || 
04895             f->frametype == AST_FRAME_DTMF_BEGIN)) {
04896             *fo = f;
04897             *rc = who;
04898             ast_debug(1, "Got DTMF %s on channel (%s)\n", 
04899                f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
04900                who->name);
04901 
04902             break;
04903          }
04904          /* Write immediately frames, not passed through jb */
04905          if (!frame_put_in_jb)
04906             ast_write(other, f);
04907             
04908          /* Check if we have to deliver now */
04909          if (jb_in_use)
04910             ast_jb_get_and_deliver(c0, c1);
04911       }
04912       /* XXX do we want to pass on also frames not matched above ? */
04913       ast_frfree(f);
04914 
04915 #ifndef HAVE_EPOLL
04916       /* Swap who gets priority */
04917       cs[2] = cs[0];
04918       cs[0] = cs[1];
04919       cs[1] = cs[2];
04920 #endif
04921    }
04922 
04923    ast_poll_channel_del(c0, c1);
04924 
04925    return res;
04926 }

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

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

Definition at line 1292 of file channel.c.

References channel_find_locked().

01293 {
01294    return channel_find_locked(NULL, NULL, 0, context, exten);
01295 }

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

Get channel by name prefix and lock it.

Get channel by name or uniqueid prefix (locks channel).

Definition at line 1279 of file channel.c.

References channel_find_locked().

Referenced by action_bridge(), ast_parse_device_state(), bridge_exec(), common_exec(), handle_cli_mixmonitor(), shared_read(), and shared_write().

01280 {
01281    return channel_find_locked(NULL, name, namelen, NULL, NULL);
01282 }

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

Get handle to channel driver based on name.

Get a channel technology structure by name.

Definition at line 610 of file channel.c.

References AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, channels, chanlist::tech, and ast_channel_tech::type.

Referenced by _ast_device_state().

00611 {
00612    struct chanlist *chanls;
00613    const struct ast_channel_tech *ret = NULL;
00614 
00615    AST_RWLIST_RDLOCK(&channels);
00616 
00617    AST_LIST_TRAVERSE(&backends, chanls, list) {
00618       if (!strcasecmp(name, chanls->tech->type)) {
00619          ret = chanls->tech;
00620          break;
00621       }
00622    }
00623 
00624    AST_RWLIST_UNLOCK(&channels);
00625    
00626    return ret;
00627 }

ast_group_t ast_get_group ( const char *  s  ) 

Definition at line 5457 of file channel.c.

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

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

05458 {
05459    char *piece;
05460    char *c;
05461    int start=0, finish=0, x;
05462    ast_group_t group = 0;
05463 
05464    if (ast_strlen_zero(s))
05465       return 0;
05466 
05467    c = ast_strdupa(s);
05468    
05469    while ((piece = strsep(&c, ","))) {
05470       if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
05471          /* Range */
05472       } else if (sscanf(piece, "%30d", &start)) {
05473          /* Just one */
05474          finish = start;
05475       } else {
05476          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
05477          continue;
05478       }
05479       for (x = start; x <= finish; x++) {
05480          if ((x > 63) || (x < 0)) {
05481             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
05482          } else
05483             group |= ((ast_group_t) 1 << x);
05484       }
05485    }
05486    return group;
05487 }

int ast_hangup ( struct ast_channel chan  ) 

Hangup a channel.

Hang up a channel.

Definition at line 1663 of file channel.c.

References ast_assert, ast_audiohook_detach_list(), ast_autoservice_stop(), ast_cause2str(), ast_cdr_detach(), ast_cdr_end(), AST_CDR_FLAG_BRIDGED, AST_CDR_FLAG_DIALED, AST_CDR_FLAG_POST_DISABLED, AST_CDR_NULL, ast_channel_free(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_closestream(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_IN_CHANNEL_LIST, AST_FLAG_ZOMBIE, ast_log(), AST_RWLIST_REMOVE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_set_flag, ast_test_flag, ast_channel::audiohooks, ast_channel::blocker, ast_channel::blockproc, ast_channel::cdr, channels, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_cdr::disposition, EVENT_FLAG_CALL, free_translation(), ast_channel::generator, ast_channel::generatordata, ast_channel_tech::hangup, ast_channel::hangupcause, LOG_ERROR, LOG_WARNING, manager_event, ast_channel::masq, ast_channel::masqr, ast_generator::release, S_OR, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::tech, and ast_channel::vstream.

Referenced by __ast_pbx_run(), __ast_request_and_dial(), __oh323_new(), action_bridge(), agent_hangup(), agent_read(), alsa_new(), answer_exec_run(), app_exec(), ast_async_goto(), ast_bridge_call_thread(), ast_call_forward(), ast_dial_destroy(), ast_dial_hangup(), ast_feature_request_and_dial(), ast_iax2_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), begin_dial_channel(), bridge_exec(), build_conf(), builtin_atxfer(), chanavail_exec(), check_compat(), check_goto_on_transfer(), clear_caller(), conf_free(), conf_run(), connect_link(), console_new(), dahdi_handle_event(), dahdi_new(), dial_exec_full(), do_forward(), do_hang(), do_idle_thread(), findmeexec(), gtalk_new(), handle_call_forward(), handle_callforward_button(), handle_enbloc_call_message(), handle_frame(), handle_frame_ownerless(), handle_hd_hf(), handle_init_event(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_soft_key_event_message(), handle_stimulus_message(), handle_timeout_trip(), handle_transfer_button(), HandleCallOutgoing(), hangup_chan(), hangupcalls(), hanguptree(), iax2_request(), iax_park(), iax_park_thread(), jingle_new(), local_hangup(), manage_parkinglot(), masq_park_call(), mgcp_new(), mgcp_ss(), monitor_dial(), mwi_thread(), nbs_new(), oss_new(), park_exec_full(), parkandannounce_exec(), phone_new(), pri_dchannel(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), ss_thread(), try_calling(), unistim_new(), usbradio_new(), wait_for_answer(), and wait_for_winner().

01664 {
01665    int res = 0;
01666 
01667    /* Don't actually hang up a channel that will masquerade as someone else, or
01668       if someone is going to masquerade as us */
01669    ast_channel_lock(chan);
01670 
01671    if (chan->audiohooks) {
01672       ast_audiohook_detach_list(chan->audiohooks);
01673       chan->audiohooks = NULL;
01674    }
01675 
01676    ast_autoservice_stop(chan);
01677 
01678    if (chan->masq) {
01679       if (ast_do_masquerade(chan))
01680          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
01681    }
01682 
01683    if (chan->masq) {
01684       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
01685       ast_channel_unlock(chan);
01686       return 0;
01687    }
01688    /* If this channel is one which will be masqueraded into something,
01689       mark it as a zombie already, so we know to free it later */
01690    if (chan->masqr) {
01691       ast_set_flag(chan, AST_FLAG_ZOMBIE);
01692       ast_channel_unlock(chan);
01693       return 0;
01694    }
01695    ast_channel_unlock(chan);
01696 
01697    AST_RWLIST_WRLOCK(&channels);
01698    if (!AST_RWLIST_REMOVE(&channels, chan, chan_list)) {
01699       ast_log(LOG_ERROR, "Unable to find channel in list to free. Assuming it has already been done.\n");
01700    }
01701    ast_clear_flag(chan, AST_FLAG_IN_CHANNEL_LIST);
01702    AST_RWLIST_UNLOCK(&channels);
01703 
01704    ast_channel_lock(chan);
01705    free_translation(chan);
01706    /* Close audio stream */
01707    if (chan->stream) {
01708       ast_closestream(chan->stream);
01709       chan->stream = NULL;
01710    }
01711    /* Close video stream */
01712    if (chan->vstream) {
01713       ast_closestream(chan->vstream);
01714       chan->vstream = NULL;
01715    }
01716    if (chan->sched) {
01717       sched_context_destroy(chan->sched);
01718       chan->sched = NULL;
01719    }
01720    
01721    if (chan->generatordata)   /* Clear any tone stuff remaining */
01722       if (chan->generator && chan->generator->release)
01723          chan->generator->release(chan, chan->generatordata);
01724    chan->generatordata = NULL;
01725    chan->generator = NULL;
01726    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01727       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
01728                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
01729                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
01730       ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0);
01731    }
01732    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
01733       ast_debug(1, "Hanging up channel '%s'\n", chan->name);
01734       if (chan->tech->hangup)
01735          res = chan->tech->hangup(chan);
01736    } else {
01737       ast_debug(1, "Hanging up zombie '%s'\n", chan->name);
01738    }
01739          
01740    ast_channel_unlock(chan);
01741    manager_event(EVENT_FLAG_CALL, "Hangup",
01742          "Channel: %s\r\n"
01743          "Uniqueid: %s\r\n"
01744          "CallerIDNum: %s\r\n"
01745          "CallerIDName: %s\r\n"
01746          "Cause: %d\r\n"
01747          "Cause-txt: %s\r\n",
01748          chan->name,
01749          chan->uniqueid,
01750          S_OR(chan->cid.cid_num, "<unknown>"),
01751          S_OR(chan->cid.cid_name, "<unknown>"),
01752          chan->hangupcause,
01753          ast_cause2str(chan->hangupcause)
01754          );
01755 
01756    if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 
01757       !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 
01758        (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) {
01759       ast_channel_lock(chan);
01760          
01761       ast_cdr_end(chan->cdr);
01762       ast_cdr_detach(chan->cdr);
01763       chan->cdr = NULL;
01764       ast_channel_unlock(chan);
01765    }
01766    
01767    ast_channel_free(chan);
01768 
01769    return res;
01770 }

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

Indicates condition of channel, with payload.

Note:
Indicate a condition such as AST_CONTROL_HOLD with payload being music on hold class
Parameters:
chan channel to change the indication
condition which condition to indicate on the channel
data pointer to payload data
datalen size of payload data
Returns:
Returns 0 on success, -1 on failure

Note:
If we compare the enumeration type, which does not have any negative constants, the compiler may optimize this code away. Therefore, we must perform an integer comparison here.

Definition at line 3123 of file channel.c.

References ast_channel::_state, _XXX_AST_CONTROL_T38, ast_channel_lock, ast_channel_unlock, ast_check_hangup(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_debug, AST_FLAG_ZOMBIE, ast_get_indication_tone(), ast_log(), ast_playtones_start(), ast_playtones_stop(), AST_STATE_UP, ast_test_flag, tone_zone_sound::data, ast_channel_tech::indicate, is_visible_indication(), LOG_WARNING, ast_channel::tech, ast_channel::visible_indication, and ast_channel::zone.

Referenced by agent_hangup(), ast_bridge_call(), ast_generic_bridge(), ast_indicate(), ast_park_call_full(), bridge_native_loop(), bridge_p2p_loop(), login_exec(), manage_parkinglot(), pbx_builtin_waitexten(), transmit_audio(), transmit_t38(), and wait_for_answer().

03125 {
03126    /* By using an enum, we'll get compiler warnings for values not handled 
03127     * in switch statements. */
03128    enum ast_control_frame_type condition = _condition;
03129    const struct tone_zone_sound *ts = NULL;
03130    int res = -1;
03131 
03132    ast_channel_lock(chan);
03133 
03134    /* Don't bother if the channel is about to go away, anyway. */
03135    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
03136       ast_channel_unlock(chan);
03137       return -1;
03138    }
03139 
03140    if (chan->tech->indicate) {
03141       /* See if the channel driver can handle this condition. */
03142       res = chan->tech->indicate(chan, condition, data, datalen);
03143    }
03144 
03145    ast_channel_unlock(chan);
03146 
03147    if (!res) {
03148       /* The channel driver successfully handled this indication */
03149       if (is_visible_indication(condition)) {
03150          chan->visible_indication = condition;
03151       }
03152       return 0;
03153    }
03154 
03155    /* The channel driver does not support this indication, let's fake
03156     * it by doing our own tone generation if applicable. */
03157 
03158    /*!\note If we compare the enumeration type, which does not have any
03159     * negative constants, the compiler may optimize this code away.
03160     * Therefore, we must perform an integer comparison here. */
03161    if (_condition < 0) {
03162       /* Stop any tones that are playing */
03163       ast_playtones_stop(chan);
03164       return 0;
03165    }
03166 
03167    /* Handle conditions that we have tones for. */
03168    switch (condition) {
03169    case _XXX_AST_CONTROL_T38:
03170       /* deprecated T.38 control frame */
03171       return -1;
03172    case AST_CONTROL_T38_PARAMETERS:
03173       /* there is no way to provide 'default' behavior for these
03174        * control frames, so we need to return failure, but there
03175        * is also no value in the log message below being emitted
03176        * since failure to handle these frames is not an 'error'
03177        * so just return right now.
03178        */
03179       return -1;
03180    case AST_CONTROL_RINGING:
03181       ts = ast_get_indication_tone(chan->zone, "ring");
03182       /* It is common practice for channel drivers to return -1 if trying
03183        * to indicate ringing on a channel which is up. The idea is to let the
03184        * core generate the ringing inband. However, we don't want the
03185        * warning message about not being able to handle the specific indication
03186        * to print nor do we want ast_indicate_data to return an "error" for this
03187        * condition
03188        */
03189       if (chan->_state == AST_STATE_UP) {
03190          res = 0;
03191       }
03192       break;
03193    case AST_CONTROL_BUSY:
03194       ts = ast_get_indication_tone(chan->zone, "busy");
03195       break;
03196    case AST_CONTROL_CONGESTION:
03197       ts = ast_get_indication_tone(chan->zone, "congestion");
03198       break;
03199    case AST_CONTROL_PROGRESS:
03200    case AST_CONTROL_PROCEEDING:
03201    case AST_CONTROL_VIDUPDATE:
03202    case AST_CONTROL_SRCUPDATE:
03203    case AST_CONTROL_RADIO_KEY:
03204    case AST_CONTROL_RADIO_UNKEY:
03205    case AST_CONTROL_OPTION:
03206    case AST_CONTROL_WINK:
03207    case AST_CONTROL_FLASH:
03208    case AST_CONTROL_OFFHOOK:
03209    case AST_CONTROL_TAKEOFFHOOK:
03210    case AST_CONTROL_ANSWER:
03211    case AST_CONTROL_HANGUP:
03212    case AST_CONTROL_RING:
03213    case AST_CONTROL_HOLD:
03214    case AST_CONTROL_UNHOLD:
03215       /* Nothing left to do for these. */
03216       res = 0;
03217       break;
03218    }
03219 
03220    if (ts && ts->data[0]) {
03221       /* We have a tone to play, yay. */
03222       ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
03223       ast_playtones_start(chan, 0, ts->data, 1);
03224       res = 0;
03225       chan->visible_indication = condition;
03226    }
03227 
03228    if (res) {
03229       /* not handled */
03230       ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
03231    }
03232 
03233    return res;
03234 }

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

Definition at line 5493 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by load_module(), and reload().

05496 {
05497    ast_moh_start_ptr = start_ptr;
05498    ast_moh_stop_ptr = stop_ptr;
05499    ast_moh_cleanup_ptr = cleanup_ptr;
05500 }

int ast_internal_timing_enabled ( struct ast_channel chan  ) 

Check if the channel can run in internal timing mode.

Parameters:
chan The channel to check
Returns:
boolean

This function will return 1 if internal timing is enabled and the timing device is available.

Definition at line 3066 of file channel.c.

References ast_debug, ast_opt_internal_timing, and ast_channel::timingfd.

Referenced by add_sdp(), and ast_read_generator_actions().

03067 {
03068    int ret = ast_opt_internal_timing && chan->timingfd > -1;
03069    ast_debug(5, "Internal timing is %s (option_internal_timing=%d chan->timingfd=%d)\n", ret? "enabled": "disabled", ast_opt_internal_timing, chan->timingfd);
03070    return ret;
03071 }

static AST_LIST_HEAD_NOLOCK_STATIC ( backends  ,
chanlist   
) [static]

the list of registered channel types

void ast_moh_cleanup ( struct ast_channel chan  ) 

Definition at line 5527 of file channel.c.

References ast_moh_cleanup_ptr.

Referenced by ast_channel_free().

05528 {
05529    if (ast_moh_cleanup_ptr)
05530       ast_moh_cleanup_ptr(chan);
05531 }

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

Turn on music on hold on a given channel.

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

Definition at line 5510 of file channel.c.

References ast_moh_start_ptr, and ast_verb.

Referenced by alsa_indicate(), app_exec(), conf_run(), conf_start_moh(), console_indicate(), dahdi_indicate(), dial_exec_full(), feature_exec_app(), gtalk_indicate(), handle_setmusic(), iax2_indicate(), jingle_indicate(), key_call(), local_indicate(), mgcp_indicate(), misdn_indication(), moh_handle_digit(), monitor_dial(), oh323_indicate(), oss_indicate(), phone_indicate(), play_moh_exec(), queue_exec(), retrydial_exec(), say_periodic_announcement(), say_position(), sip_indicate(), skinny_indicate(), start_moh_exec(), TransferCallStep1(), unistim_indicate(), usbradio_indicate(), and wait_moh_exec().

05511 {
05512    if (ast_moh_start_ptr)
05513       return ast_moh_start_ptr(chan, mclass, interpclass);
05514 
05515    ast_verb(3, "Music class %s requested but no musiconhold loaded.\n", mclass ? mclass : (interpclass ? interpclass : "default"));
05516 
05517    return 0;
05518 }

void ast_moh_stop ( struct ast_channel chan  ) 
void ast_poll_channel_add ( struct ast_channel chan0,
struct ast_channel chan1 
)

Add a channel to an optimized waitfor

Definition at line 1583 of file channel.c.

References AST_MAX_FDS, and ast_channel::fds.

Referenced by ast_feature_request_and_dial(), ast_generic_bridge(), begin_dial_channel(), bridge_native_loop(), bridge_p2p_loop(), and wait_for_answer().

01584 {
01585 #ifdef HAVE_EPOLL
01586    struct epoll_event ev;
01587    int i = 0;
01588 
01589    if (chan0->epfd == -1)
01590       return;
01591 
01592    /* Iterate through the file descriptors on chan1, adding them to chan0 */
01593    for (i = 0; i < AST_MAX_FDS; i++) {
01594       if (chan1->fds[i] == -1)
01595          continue;
01596       ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
01597       ev.data.ptr = chan1->epfd_data[i];
01598       epoll_ctl(chan0->epfd, EPOLL_CTL_ADD, chan1->fds[i], &ev);
01599    }
01600 
01601 #endif
01602    return;
01603 }

void ast_poll_channel_del ( struct ast_channel chan0,
struct ast_channel chan1 
)

Delete a channel from an optimized waitfor

Definition at line 1606 of file channel.c.

References AST_MAX_FDS, and ast_channel::fds.

Referenced by ast_feature_request_and_dial(), ast_generic_bridge(), bridge_native_loop(), bridge_p2p_loop(), monitor_dial(), and wait_for_answer().

01607 {
01608 #ifdef HAVE_EPOLL
01609    struct epoll_event ev;
01610    int i = 0;
01611 
01612    if (chan0->epfd == -1)
01613       return;
01614 
01615    for (i = 0; i < AST_MAX_FDS; i++) {
01616       if (chan1->fds[i] == -1)
01617          continue;
01618       epoll_ctl(chan0->epfd, EPOLL_CTL_DEL, chan1->fds[i], &ev);
01619    }
01620 
01621 #endif
01622    return;
01623 }

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

Print call group and pickup group ---.

print call- and pickup groups into buffer

Definition at line 5539 of file channel.c.

References first, and num.

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

05540 {
05541    unsigned int i;
05542    int first = 1;
05543    char num[3];
05544 
05545    buf[0] = '\0';
05546    
05547    if (!group) /* Return empty string if no group */
05548       return buf;
05549 
05550    for (i = 0; i <= 63; i++) {   /* Max group is 63 */
05551       if (group & ((ast_group_t) 1 << i)) {
05552             if (!first) {
05553             strncat(buf, ", ", buflen - strlen(buf) - 1);
05554          } else {
05555             first = 0;
05556          }
05557          snprintf(num, sizeof(num), "%u", i);
05558          strncat(buf, num, buflen - strlen(buf) - 1);
05559       }
05560    }
05561    return buf;
05562 }

int ast_prod ( struct ast_channel chan  ) 

Send empty audio to prime a channel driver.

Definition at line 3355 of file channel.c.

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

Referenced by ast_activate_generator().

03356 {
03357    struct ast_frame a = { AST_FRAME_VOICE };
03358    char nothing[128];
03359 
03360    /* Send an empty audio frame to get things moving */
03361    if (chan->_state != AST_STATE_UP) {
03362       ast_debug(1, "Prodding channel '%s'\n", chan->name);
03363       a.subclass = chan->rawwriteformat;
03364       a.data.ptr = nothing + AST_FRIENDLY_OFFSET;
03365       a.src = "ast_prod";
03366       if (ast_write(chan, &a))
03367          ast_log(LOG_WARNING, "Prodding channel '%s' failed\n", chan->name);
03368    }
03369    return 0;
03370 }

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

Queue a control frame with payload.

Parameters:
chan channel to queue frame onto
control type of control frame
data pointer to payload data to be included in frame
datalen number of bytes of payload data
Return values:
0 success
non-zero failure

The supplied payload data is copied into the frame, so the caller's copy is not modified nor freed, and the resulting frame will retain a copy of the data even if the caller frees their local copy.

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

Definition at line 1128 of file channel.c.

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

Referenced by change_t38_state(), dahdi_handle_event(), dahdi_hangup(), iax2_queue_control_data(), process_sdp(), and skinny_hold().

01130 {
01131    struct ast_frame f = { AST_FRAME_CONTROL, };
01132 
01133    f.subclass = control;
01134    f.data.ptr = (void *) data;
01135    f.datalen = datalen;
01136 
01137    return ast_queue_frame(chan, &f);
01138 }

int ast_queue_frame ( struct ast_channel chan,
struct ast_frame f 
)

Queue one or more frames to a channel's frame queue.

Parameters:
chan the channel to queue the frame(s) on
f the frame(s) to queue. Note that the frame(s) will be duplicated by this function. It is the responsibility of the caller to handle freeing the memory associated with the frame(s) being passed if necessary.
Return values:
0 success
non-zero failure

Definition at line 1075 of file channel.c.

References __ast_queue_frame().

Referenced by __ast_read(), __oh323_rtp_create(), __oh323_update_info(), action_atxfer(), agent_new(), alsa_call(), ast_channel_masquerade(), ast_channel_setwhentohangup_tv(), ast_do_masquerade(), ast_dsp_process(), ast_queue_control(), ast_queue_control_data(), ast_queue_hangup(), ast_queue_hangup_with_cause(), ast_softhangup_nolock(), cb_events(), cli_console_answer(), cli_console_dial(), cli_console_flash(), cli_console_sendtext(), console_answer(), console_call(), console_dial(), console_do_answer(), console_flash(), console_sendtext(), dahdi_queue_frame(), dictate_exec(), do_immediate_setup(), gtalk_handle_dtmf(), handle_keypad_button_message(), handle_request_info(), handle_request_invite(), handle_response_invite(), iax2_queue_frame(), jingle_handle_dtmf(), local_queue_frame(), mgcp_queue_frame(), oh323_simulate_dtmf_end(), oss_call(), process_sdp(), queue_dtmf_readq(), receive_digit(), receive_message(), rpt_call(), stream_monitor(), unistim_do_senddigit(), unistim_senddigit_end(), usbradio_read(), and wakeup_sub().

01076 {
01077    return __ast_queue_frame(chan, fin, 0, NULL);
01078 }

int ast_queue_frame_head ( struct ast_channel chan,
struct ast_frame f 
)

Queue one or more frames to the head of a channel's frame queue.

Parameters:
chan the channel to queue the frame(s) on
f the frame(s) to queue. Note that the frame(s) will be duplicated by this function. It is the responsibility of the caller to handle freeing the memory associated with the frame(s) being passed if necessary.
Return values:
0 success
non-zero failure

Definition at line 1080 of file channel.c.

References __ast_queue_frame().

Referenced by __ast_answer(), __ast_read(), and ast_autoservice_stop().

01081 {
01082    return __ast_queue_frame(chan, fin, 1, NULL);
01083 }

int ast_queue_hangup ( struct ast_channel chan  ) 
int ast_queue_hangup_with_cause ( struct ast_channel chan,
int  cause 
)

Queue a hangup frame for channel.

Queue a hangup frame with hangupcause set.

Definition at line 1098 of file channel.c.

References ast_channel::_softhangup, ast_channel_trylock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FRAME_CONTROL, ast_queue_frame(), AST_SOFTHANGUP_DEV, ast_frame::data, ast_channel::hangupcause, and ast_frame::uint32.

Referenced by __oh323_update_info(), __sip_autodestruct(), close_call(), close_client(), console_hangup(), dahdi_handle_event(), handle_request_bye(), handle_response(), handle_response_invite(), handle_response_notify(), HandleCallOutgoing(), hangup_chan(), hangup_connection(), misdn_answer(), pri_hangup_all(), retrans_pkt(), and TransferCallStep1().

01099 {
01100    struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_HANGUP };
01101 
01102    if (cause >= 0)
01103       f.data.uint32 = cause;
01104 
01105    /* Yeah, let's not change a lock-critical value without locking */
01106    if (!ast_channel_trylock(chan)) {
01107       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01108       if (cause < 0)
01109          f.data.uint32 = chan->hangupcause;
01110 
01111       ast_channel_unlock(chan);
01112    }
01113 
01114    return ast_queue_frame(chan, &f);
01115 }

int ast_raw_answer ( struct ast_channel chan,
int  cdr_answer 
)

Answer a channel.

Parameters:
chan channel to answer
cdr_answer flag to control whether any associated CDR should be marked as 'answered'

This function answers a channel and handles all necessary call setup functions.

Note:
The channel passed does not need to be locked, but is locked by the function when needed.
Unlike ast_answer(), this function will not wait for media flow to begin. The caller should be careful before sending media to the channel before incoming media arrives, as the outgoing media may be lost.
Return values:
0 on success
non-zero on failure

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

Referenced by __ast_answer(), and ast_bridge_call().

01773 {
01774    int res = 0;
01775 
01776    ast_channel_lock(chan);
01777 
01778    /* You can't answer an outbound call */
01779    if (ast_test_flag(chan, AST_FLAG_OUTGOING)) {
01780       ast_channel_unlock(chan);
01781       return 0;
01782    }
01783 
01784    /* Stop if we're a zombie or need a soft hangup */
01785    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
01786       ast_channel_unlock(chan);
01787       return -1;
01788    }
01789 
01790    ast_channel_unlock(chan);
01791 
01792    switch (chan->_state) {
01793    case AST_STATE_RINGING:
01794    case AST_STATE_RING:
01795       ast_channel_lock(chan);
01796       if (chan->tech->answer) {
01797          res = chan->tech->answer(chan);
01798       }
01799       ast_setstate(chan, AST_STATE_UP);
01800       if (cdr_answer) {
01801          ast_cdr_answer(chan->cdr);
01802       }
01803       ast_channel_unlock(chan);
01804       break;
01805    case AST_STATE_UP:
01806       /* Calling ast_cdr_answer when it it has previously been called
01807        * is essentially a no-op, so it is safe.
01808        */
01809       if (cdr_answer) {
01810          ast_cdr_answer(chan->cdr);
01811       }
01812       break;
01813    default:
01814       break;
01815    }
01816 
01817    ast_indicate(chan, -1);
01818    chan->visible_indication = 0;
01819 
01820    return res;
01821 }

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

Reads a frame.

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

Definition at line 3073 of file channel.c.

References __ast_read().

Referenced by __adsi_transmit_messages(), __ast_answer(), __ast_play_and_record(), __ast_request_and_dial(), adsi_careful_send(), agent_ack_sleep(), agent_read(), ast_feature_request_and_dial(), ast_generic_bridge(), ast_recvtext(), ast_safe_sleep_conditional(), ast_tonepair(), ast_udptl_bridge(), ast_waitfordigit_full(), async_wait(), autoservice_run(), background_detect_exec(), bridge_native_loop(), bridge_p2p_loop(), builtin_atxfer(), channel_spy(), check_goto_on_transfer(), conf_exec(), conf_flush(), conf_run(), dahdi_bridge(), dial_exec_full(), dictate_exec(), disa_exec(), do_idle_thread(), do_waiting(), echo_exec(), eivr_comm(), find_cache(), handle_recordfile(), handle_speechrecognize(), iax2_bridge(), iax_park_thread(), ices_exec(), isAnsweringMachine(), jack_exec(), launch_asyncagi(), manage_parkinglot(), masq_park_call(), measurenoise(), misdn_bridge(), monitor_dial(), mp3_exec(), NBScat_exec(), receive_dtmf_digits(), record_exec(), recordthread(), rpt(), rpt_exec(), run_agi(), send_tone_burst(), send_waveform_to_channel(), sendurl_exec(), speech_background(), ss_thread(), transmit_audio(), transmit_t38(), wait_for_answer(), wait_for_hangup(), wait_for_winner(), waitforring_exec(), and waitstream_core().

03074 {
03075    return __ast_read(chan, 0);
03076 }

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

Definition at line 2503 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_deactivate_generator(), ast_debug, ast_format_rate(), AST_FRAME_CNG, ast_internal_timing_enabled(), ast_settimeout(), ast_frame::datalen, ast_frame::frametype, ast_generator::generate, ast_channel::generator, generator_force(), ast_channel::generatordata, ast_frame::samples, ast_frame::subclass, ast_channel::timingfd, ast_channel::timingfunc, and ast_channel::writeformat.

Referenced by __ast_read().

02504 {
02505    if (chan->generator && chan->generator->generate && chan->generatordata &&  !ast_internal_timing_enabled(chan)) {
02506       void *tmp = chan->generatordata;
02507       int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = chan->generator->generate;
02508       int res;
02509       int samples;
02510 
02511       if (chan->timingfunc) {
02512          ast_debug(1, "Generator got voice, switching to phase locked mode\n");
02513          ast_settimeout(chan, 0, NULL, NULL);
02514       }
02515 
02516       chan->generatordata = NULL;     /* reset, to let writes go through */
02517 
02518       if (f->subclass != chan->writeformat) {
02519          float factor;
02520          factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass));
02521          samples = (int) ( ((float) f->samples) * factor );
02522       } else {
02523          samples = f->samples;
02524       }
02525       
02526       /* This unlock is here based on two assumptions that hold true at this point in the
02527        * code. 1) this function is only called from within __ast_read() and 2) all generators
02528        * call ast_write() in their generate callback.
02529        *
02530        * The reason this is added is so that when ast_write is called, the lock that occurs 
02531        * there will not recursively lock the channel. Doing this will cause intended deadlock 
02532        * avoidance not to work in deeper functions
02533        */
02534       ast_channel_unlock(chan);
02535       res = generate(chan, tmp, f->datalen, samples);
02536       ast_channel_lock(chan);
02537       chan->generatordata = tmp;
02538       if (res) {
02539          ast_debug(1, "Auto-deactivating generator\n");
02540          ast_deactivate_generator(chan);
02541       }
02542 
02543    } else if (f->frametype == AST_FRAME_CNG) {
02544       if (chan->generator && !chan->timingfunc && (chan->timingfd > -1)) {
02545          ast_debug(1, "Generator got CNG, switching to timed mode\n");
02546          ast_settimeout(chan, 50, generator_force, chan);
02547       }
02548    }
02549 }

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

Reads a frame, returning AST_FRAME_NULL frame if audio.

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

Definition at line 3078 of file channel.c.

References __ast_read().

Referenced by conf_run().

03079 {
03080    return __ast_read(chan, 1);
03081 }

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

Reads multiple digits

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

Definition at line 4060 of file channel.c.

References ast_readstring_full().

Referenced by __adsi_transmit_messages(), _ast_adsi_begin_download(), _ast_adsi_get_cpeinfo(), _ast_adsi_load_session(), ast_app_getdata(), dialout(), do_directory(), forward_message(), privacy_exec(), vm_authenticate(), vm_newuser(), and vm_options().

04061 {
04062    return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
04063 }

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

Definition at line 4065 of file channel.c.

References ast_check_hangup(), AST_DIGIT_ANY, AST_FLAG_ZOMBIE, AST_GETDATA_COMPLETE, AST_GETDATA_EMPTY_END_TERMINATED, AST_GETDATA_FAILED, AST_GETDATA_INTERRUPTED, AST_GETDATA_TIMEOUT, ast_stopstream(), ast_test_flag, ast_waitfordigit_full(), ast_waitstream_full(), and ast_channel::stream.

Referenced by ast_app_getdata_full(), and ast_readstring().

04066 {
04067    int pos = 0;   /* index in the buffer where we accumulate digits */
04068    int to = ftimeout;
04069 
04070    /* Stop if we're a zombie or need a soft hangup */
04071    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
04072       return -1;
04073    if (!len)
04074       return -1;
04075    for (;;) {
04076       int d;
04077       if (c->stream) {
04078          d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
04079          ast_stopstream(c);
04080          usleep(1000);
04081          if (!d)
04082             d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
04083       } else {
04084          d = ast_waitfordigit_full(c, to, audiofd, ctrlfd);
04085       }
04086       if (d < 0)
04087          return AST_GETDATA_FAILED;
04088       if (d == 0) {
04089          s[pos] = '\0';
04090          return AST_GETDATA_TIMEOUT;
04091       }
04092       if (d == 1) {
04093          s[pos] = '\0';
04094          return AST_GETDATA_INTERRUPTED;
04095       }
04096       if (strchr(enders, d) && (pos == 0)) {
04097          s[pos] = '\0';
04098          return AST_GETDATA_EMPTY_END_TERMINATED;
04099       }
04100       if (!strchr(enders, d)) {
04101          s[pos++] = d;
04102       }
04103       if (strchr(enders, d) || (pos >= len)) {
04104          s[pos] = '\0';
04105          return AST_GETDATA_COMPLETE;
04106       }
04107       to = timeout;
04108    }
04109    /* Never reached */
04110    return 0;
04111 }

int ast_recvchar ( struct ast_channel chan,
int  timeout 
)

Receives a text character from a channel.

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

Definition at line 3236 of file channel.c.

References ast_free, and ast_recvtext().

Referenced by handle_recvchar().

03237 {
03238    int c;
03239    char *buf = ast_recvtext(chan, timeout);
03240    if (buf == NULL)
03241       return -1;  /* error or timeout */
03242    c = *(unsigned char *)buf;
03243    ast_free(buf);
03244    return c;
03245 }

char* ast_recvtext ( struct ast_channel chan,
int  timeout 
)

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

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

Definition at line 3247 of file channel.c.

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

Referenced by ast_recvchar(), and handle_recvtext().

03248 {
03249    int res, done = 0;
03250    char *buf = NULL;
03251    
03252    while (!done) {
03253       struct ast_frame *f;
03254       if (ast_check_hangup(chan))
03255          break;
03256       res = ast_waitfor(chan, timeout);
03257       if (res <= 0) /* timeout or error */
03258          break;
03259       timeout = res; /* update timeout */
03260       f = ast_read(chan);
03261       if (f == NULL)
03262          break; /* no frame */
03263       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP)
03264          done = 1;   /* force a break */
03265       else if (f->frametype == AST_FRAME_TEXT) {      /* what we want */
03266          buf = ast_strndup((char *) f->data.ptr, f->datalen);  /* dup and break */
03267          done = 1;
03268       }
03269       ast_frfree(f);
03270    }
03271    return buf;
03272 }

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

Requests a channel.

Parameters:
type type of channel to request
format requested channel format (codec)
data data to pass to the channel requester
status status

Request a channel of a given type, with data as optional information used by the low level module

Return values:
NULL failure
non-NULL channel on success

Definition at line 3958 of file channel.c.

References AST_CAUSE_BEARERCAPABILITY_NOTAVAIL, AST_CAUSE_NOSUCHDRIVER, AST_CAUSE_NOTDEFINED, AST_FORMAT_AUDIO_MASK, AST_FORMAT_TEXT_MASK, AST_FORMAT_VIDEO_MASK, AST_LIST_TRAVERSE, ast_log(), AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_translator_best_choice(), ast_channel_tech::capabilities, capabilities, channels, LOG_WARNING, ast_channel_tech::requester, chanlist::tech, and ast_channel_tech::type.

Referenced by __ast_request_and_dial(), agent_request(), ast_call_forward(), ast_feature_request_and_dial(), attempt_reconnect(), begin_dial_channel(), build_conf(), chanavail_exec(), conf_run(), connect_link(), dial_exec_full(), do_forward(), findmeexec(), ring_entry(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), and wait_for_answer().

03959 {
03960    struct chanlist *chan;
03961    struct ast_channel *c;
03962    int capabilities;
03963    int fmt;
03964    int res;
03965    int foo;
03966    int videoformat = format & AST_FORMAT_VIDEO_MASK;
03967    int textformat = format & AST_FORMAT_TEXT_MASK;
03968 
03969    if (!cause)
03970       cause = &foo;
03971    *cause = AST_CAUSE_NOTDEFINED;
03972 
03973    if (AST_RWLIST_RDLOCK(&channels)) {
03974       ast_log(LOG_WARNING, "Unable to lock channel list\n");
03975       return NULL;
03976    }
03977 
03978    AST_LIST_TRAVERSE(&backends, chan, list) {
03979       if (strcasecmp(type, chan->tech->type))
03980          continue;
03981 
03982       capabilities = chan->tech->capabilities;
03983       fmt = format & AST_FORMAT_AUDIO_MASK;
03984       if (fmt) {
03985          /* We have audio - is it possible to connect the various calls to each other? 
03986             (Avoid this check for calls without audio, like text+video calls)
03987          */
03988          res = ast_translator_best_choice(&fmt, &capabilities);
03989          if (res < 0) {
03990             ast_log(LOG_WARNING, "No translator path exists for channel type %s (native 0x%x) to 0x%x\n", type, chan->tech->capabilities, format);
03991             *cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
03992             AST_RWLIST_UNLOCK(&channels);
03993             return NULL;
03994          }
03995       }
03996       AST_RWLIST_UNLOCK(&channels);
03997       if (!chan->tech->requester)
03998          return NULL;
03999       
04000       if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, data, cause)))
04001          return NULL;
04002       
04003       /* no need to generate a Newchannel event here; it is done in the channel_alloc call */
04004       return c;
04005    }
04006 
04007    ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
04008    *cause = AST_CAUSE_NOSUCHDRIVER;
04009    AST_RWLIST_UNLOCK(&channels);
04010 
04011    return NULL;
04012 }

struct ast_channel* ast_request_and_dial ( const char *  type,
int  format,
void *  data,
int  timeout,
int *  reason,
const char *  cid_num,
const char *  cid_name 
) [read]

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

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

Definition at line 3953 of file channel.c.

References __ast_request_and_dial().

Referenced by ast_pbx_outgoing_exten().

03954 {
03955    return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
03956 }

static AST_RWLIST_HEAD_STATIC ( channels  ,
ast_channel   
) [static]

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

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

Wait, look for hangups and condition arg.

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

Definition at line 1305 of file channel.c.

References ast_channel_start_silence_generator(), ast_channel_stop_silence_generator(), ast_frfree, ast_opt_transmit_silence, ast_read(), ast_waitfor(), cond, f, and ast_channel::generatordata.

Referenced by ast_safe_sleep(), and login_exec().

01306 {
01307    struct ast_frame *f;
01308    struct ast_silence_generator *silgen = NULL;
01309    int res = 0;
01310 
01311    /* If no other generator is present, start silencegen while waiting */
01312    if (ast_opt_transmit_silence && !chan->generatordata) {
01313       silgen = ast_channel_start_silence_generator(chan);
01314    }
01315 
01316    while (ms > 0) {
01317       if (cond && ((*cond)(data) == 0)) {
01318          break;
01319       }
01320       ms = ast_waitfor(chan, ms);
01321       if (ms < 0) {
01322          res = -1;
01323          break;
01324       }
01325       if (ms > 0) {
01326          f = ast_read(chan);
01327          if (!f) {
01328             res = -1;
01329             break;
01330          }
01331          ast_frfree(f);
01332       }
01333    }
01334 
01335    /* stop silgen if present */
01336    if (silgen) {
01337       ast_channel_stop_silence_generator(chan, silgen);
01338    }
01339 
01340    return res;
01341 }

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

Definition at line 5811 of file channel.c.

References ast_say_character_str_full.

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

05813 {
05814    return ast_say_character_str_full(chan, str, ints, lang, -1, -1);
05815 }

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

Definition at line 5805 of file channel.c.

References ast_say_digit_str_full.

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

05807 {
05808    return ast_say_digit_str_full(chan, str, ints, lang, -1, -1);
05809 }

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

Definition at line 5799 of file channel.c.

References ast_say_digits_full().

Referenced by ast_park_call_full(), common_exec(), conf_exec(), conf_run(), parkandannounce_exec(), and rpt_tele_thread().

05801 {
05802    return ast_say_digits_full(chan, num, ints, lang, -1, -1);
05803 }

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 
)

Definition at line 5787 of file channel.c.

References ast_say_number_full.

Referenced by ast_say_date_da(), ast_say_date_de(), ast_say_date_en(), ast_say_date_fr(), ast_say_date_gr(), ast_say_date_he(), ast_say_date_hu(), ast_say_date_ka(), ast_say_date_nl(), ast_say_date_pt(), ast_say_date_th(), ast_say_date_with_format_da(), ast_say_date_with_format_de(), ast_say_date_with_format_en(), ast_say_date_with_format_es(), ast_say_date_with_format_fr(), ast_say_date_with_format_it(), ast_say_date_with_format_nl(), ast_say_date_with_format_pl(), ast_say_date_with_format_pt(), ast_say_date_with_format_th(), ast_say_datetime_en(), ast_say_datetime_fr(), ast_say_datetime_from_now_en(), ast_say_datetime_from_now_fr(), ast_say_datetime_from_now_he(), ast_say_datetime_from_now_ka(), ast_say_datetime_from_now_pt(), ast_say_datetime_he(), ast_say_datetime_pt(), ast_say_datetime_th(), ast_say_datetime_zh(), ast_say_time_de(), ast_say_time_en(), ast_say_time_fr(), ast_say_time_gr(), ast_say_time_hu(), ast_say_time_ka(), ast_say_time_nl(), ast_say_time_pt(), ast_say_time_pt_BR(), ast_say_time_th(), ast_say_time_zh(), bridge_playfile(), conf_exec(), conf_run(), count_exec(), dictate_exec(), get_folder(), gr_say_number_female(), pbx_builtin_saynumber(), play_message(), play_message_duration(), rpt_tele_thread(), say_and_wait(), say_position(), saynum(), try_calling(), vm_intro_gr(), vm_intro_he(), vm_intro_multilang(), vm_intro_pt(), and vm_intro_pt_BR().

05789 {
05790    return ast_say_number_full(chan, num, ints, language, options, -1, -1);
05791 }

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

Definition at line 5817 of file channel.c.

References ast_say_phonetic_str_full.

Referenced by pbx_builtin_sayphonetic().

05819 {
05820    return ast_say_phonetic_str_full(chan, str, ints, lang, -1, -1);
05821 }

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

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

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

Definition at line 3345 of file channel.c.

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

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

03346 {
03347    if (chan->tech->send_digit_begin) {
03348       ast_senddigit_begin(chan, digit);
03349       ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
03350    }
03351    
03352    return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION));
03353 }

int ast_senddigit_begin ( struct ast_channel chan,
char  digit 
)

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

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

Definition at line 3287 of file channel.c.

References ast_debug, ast_playtones_start(), ast_channel_tech::send_digit_begin, and ast_channel::tech.

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

03288 {
03289    /* Device does not support DTMF tones, lets fake
03290     * it by doing our own generation. */
03291    static const char* dtmf_tones[] = {
03292       "941+1336", /* 0 */
03293       "697+1209", /* 1 */
03294       "697+1336", /* 2 */
03295       "697+1477", /* 3 */
03296       "770+1209", /* 4 */
03297       "770+1336", /* 5 */
03298       "770+1477", /* 6 */
03299       "852+1209", /* 7 */
03300       "852+1336", /* 8 */
03301       "852+1477", /* 9 */
03302       "697+1633", /* A */
03303       "770+1633", /* B */
03304       "852+1633", /* C */
03305       "941+1633", /* D */
03306       "941+1209", /* * */
03307       "941+1477"  /* # */
03308    };
03309 
03310    if (!chan->tech->send_digit_begin)
03311       return 0;
03312 
03313    if (!chan->tech->send_digit_begin(chan, digit))
03314       return 0;
03315 
03316    if (digit >= '0' && digit <='9')
03317       ast_playtones_start(chan, 0, dtmf_tones[digit-'0'], 0);
03318    else if (digit >= 'A' && digit <= 'D')
03319       ast_playtones_start(chan, 0, dtmf_tones[digit-'A'+10], 0);
03320    else if (digit == '*')
03321       ast_playtones_start(chan, 0, dtmf_tones[14], 0);
03322    else if (digit == '#')
03323       ast_playtones_start(chan, 0, dtmf_tones[15], 0);
03324    else {
03325       /* not handled */
03326       ast_debug(1, "Unable to generate DTMF tone '%c' for '%s'\n", digit, chan->name);
03327    }
03328 
03329    return 0;
03330 }

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

Send a DTMF digit to a channel.

Send a DTMF digit to a channel.

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

Definition at line 3332 of file channel.c.

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

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

03333 {
03334    int res = -1;
03335 
03336    if (chan->tech->send_digit_end)
03337       res = chan->tech->send_digit_end(chan, digit, duration);
03338 
03339    if (res && chan->generator)
03340       ast_playtones_stop(chan);
03341    
03342    return 0;
03343 }

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

Sends text to a channel.

Parameters:
chan channel to act upon
text string of text to send on the channel

Write text to a display on a channel

Note:
The channel does not need to be locked before calling this function.
Return values:
0 on success
-1 on failure

Definition at line 3274 of file channel.c.

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

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

03275 {
03276    int res = 0;
03277    /* Stop if we're a zombie or need a soft hangup */
03278    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
03279       return -1;
03280    CHECK_BLOCKING(chan);
03281    if (chan->tech->send_text)
03282       res = chan->tech->send_text(chan, text);
03283    ast_clear_flag(chan, AST_FLAG_BLOCKING);
03284    return res;
03285 }

void ast_set_callerid ( struct ast_channel chan,
const char *  cid_num,
const char *  cid_name,
const char *  cid_ani 
)

Set caller ID number, name and ANI.

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

Definition at line 4642 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_free, ast_strdup, ast_channel::cid, ast_callerid::cid_ani, ast_callerid::cid_name, ast_callerid::cid_num, and report_new_callerid().

Referenced by __ast_request_and_dial(), agent_call(), ast_call_forward(), ast_feature_request_and_dial(), callerid_write(), dahdi_read(), dial_exec_full(), disa_exec(), do_forward(), findmeexec(), handle_setcallerid(), mgcp_ss(), privacy_exec(), read_config(), rpt_exec(), skinny_newcall(), and ss_thread().

04643 {
04644    ast_channel_lock(chan);
04645 
04646    if (cid_num) {
04647       if (chan->cid.cid_num)
04648          ast_free(chan->cid.cid_num);
04649       chan->cid.cid_num = ast_strdup(cid_num);
04650    }
04651    if (cid_name) {
04652       if (chan->cid.cid_name)
04653          ast_free(chan->cid.cid_name);
04654       chan->cid.cid_name = ast_strdup(cid_name);
04655    }
04656    if (cid_ani) {
04657       if (chan->cid.cid_ani)
04658          ast_free(chan->cid.cid_ani);
04659       chan->cid.cid_ani = ast_strdup(cid_ani);
04660    }
04661 
04662    report_new_callerid(chan);
04663 
04664    ast_channel_unlock(chan);
04665 }

int ast_set_read_format ( struct ast_channel chan,
int  format 
)
void ast_set_variables ( struct ast_channel chan,
struct ast_variable vars 
)

adds a list of channel variables to a channel

Parameters:
chan the channel
vars a linked list of variables

Variable names can be for a regular channel variable or a dialplan function that has the ability to be written to.

Definition at line 5564 of file channel.c.

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

Referenced by __ast_request_and_dial(), ast_call_forward(), ast_pbx_outgoing_app(), and ast_pbx_outgoing_exten().

05565 {
05566    struct ast_variable *cur;
05567 
05568    for (cur = vars; cur; cur = cur->next)
05569       pbx_builtin_setvar_helper(chan, cur->name, cur->value);  
05570 }

int ast_set_write_format ( struct ast_channel chan,
int  format 
)
int ast_setstate ( struct ast_channel chan,
enum ast_channel_state  state 
)

Change the state of a channel.

Definition at line 4667 of file channel.c.

References ast_channel::_state, AST_CHANNEL_NAME, ast_copy_string(), AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), ast_state2str(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, EVENT_FLAG_CALL, manager_event, name, and S_OR.

Referenced by __ast_read(), __dahdi_exception(), __oh323_update_info(), agent_call(), alsa_answer(), ast_raw_answer(), cb_events(), check_availability(), console_answer(), dahdi_answer(), dahdi_call(), dahdi_handle_event(), dahdi_indicate(), dahdi_read(), do_bridge_masquerade(), gtalk_call(), gtalk_newcall(), handle_invite_replaces(), handle_offhook_message(), handle_request_invite(), handle_response_invite(), handle_soft_key_event_message(), handle_stimulus_message(), iax2_call(), jingle_call(), jingle_newcall(), local_queue_frame(), mgcp_answer(), mgcp_call(), mgcp_ss(), misdn_call(), misdn_indication(), nbs_call(), nbs_hangup(), oh323_answer(), oss_answer(), pbx_builtin_busy(), pbx_builtin_congestion(), phone_answer(), phone_call(), phone_exception(), phone_hangup(), phone_write(), release_chan(), release_chan_early(), sip_answer(), skinny_answer(), skinny_call(), skinny_newcall(), ss_thread(), unistim_answer(), unistim_call(), unistim_new(), unistim_ss(), update_state(), usbradio_answer(), and usbradio_call().

04668 {
04669    int oldstate = chan->_state;
04670    char name[AST_CHANNEL_NAME], *dashptr;
04671 
04672    if (oldstate == state)
04673       return 0;
04674 
04675    ast_copy_string(name, chan->name, sizeof(name));
04676    if ((dashptr = strrchr(name, '-'))) {
04677       *dashptr = '\0';
04678    }
04679 
04680    chan->_state = state;
04681 
04682    /* We have to pass AST_DEVICE_UNKNOWN here because it is entirely possible that the channel driver
04683     * for this channel is using the callback method for device state. If we pass in an actual state here
04684     * we override what they are saying the state is and things go amuck. */
04685    ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
04686 
04687    /* setstate used to conditionally report Newchannel; this is no more */
04688    manager_event(EVENT_FLAG_CALL,
04689             "Newstate",
04690             "Channel: %s\r\n"
04691             "ChannelState: %d\r\n"
04692             "ChannelStateDesc: %s\r\n"
04693             "CallerIDNum: %s\r\n"
04694             "CallerIDName: %s\r\n"
04695             "Uniqueid: %s\r\n",
04696             chan->name, chan->_state, ast_state2str(chan->_state),
04697             S_OR(chan->cid.cid_num, ""),
04698             S_OR(chan->cid.cid_name, ""),
04699             chan->uniqueid);
04700 
04701    return 0;
04702 }

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

Enable or disable timer ticks for a channel.

Parameters:
rate number of timer ticks per second

If timers are supported, force a scheduled expiration on the timer fd, at which point we call the callback function / data

Call this function with a rate of 0 to turn off the timer ticks

Version:
1.6.1 changed samples parameter to rate, accomodates new timing methods

Definition at line 2378 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_debug, ast_timer_get_max_rate(), ast_timer_set_rate(), ast_channel::timer, ast_channel::timingdata, ast_channel::timingfd, and ast_channel::timingfunc.

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

02379 {
02380    int res;
02381    unsigned int real_rate = rate, max_rate;
02382 
02383    ast_channel_lock(c);
02384 
02385    if (c->timingfd == -1) {
02386       ast_channel_unlock(c);
02387       return -1;
02388    }
02389 
02390    if (!func) {
02391       rate = 0;
02392       data = NULL;
02393    }
02394 
02395    if (rate && rate > (max_rate = ast_timer_get_max_rate(c->timer))) {
02396       real_rate = max_rate;
02397    }
02398 
02399    ast_debug(1, "Scheduling timer at (%u requested / %u actual) timer ticks per second\n", rate, real_rate);
02400 
02401    res = ast_timer_set_rate(c->timer, real_rate);
02402 
02403    c->timingfunc = func;
02404    c->timingdata = data;
02405 
02406    ast_channel_unlock(c);
02407 
02408    return res;
02409 }

int ast_shutting_down ( void   ) 

Returns non-zero if Asterisk is being shut down.

Returns non-zero if Asterisk is being shut down

Definition at line 516 of file channel.c.

Referenced by handle_request_options().

00517 {
00518    return shutting_down;
00519 }

int ast_softhangup ( struct ast_channel chan,
int  cause 
)
int ast_softhangup_nolock ( struct ast_channel chan,
int  cause 
)

Softly hangup a channel, don't lock.

Softly hangup up a channel (no channel lock).

Definition at line 1626 of file channel.c.

References ast_channel::_softhangup, ast_debug, AST_FLAG_BLOCKING, ast_null_frame, ast_queue_frame(), ast_test_flag, and ast_channel::blocker.

Referenced by ast_async_goto(), ast_softhangup(), attempt_transfer(), check_rtp_timeout(), dahdi_softhangup_all(), oh323_indicate(), proc_session_timer(), sip_indicate(), and skinny_indicate().

01627 {
01628    ast_debug(1, "Soft-Hanging up channel '%s'\n", chan->name);
01629    /* Inform channel driver that we need to be hung up, if it cares */
01630    chan->_softhangup |= cause;
01631    ast_queue_frame(chan, &ast_null_frame);
01632    /* Interrupt any poll call or such */
01633    if (ast_test_flag(chan, AST_FLAG_BLOCKING))
01634       pthread_kill(chan->blocker, SIGURG);
01635    return 0;
01636 }

const char* ast_state2str ( enum ast_channel_state  state  ) 

Gives the string form of a given channel state.

Note:
This function is not reentrant.

Definition at line 657 of file channel.c.

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

Referenced by __ast_channel_alloc_ap(), action_coreshowchannels(), action_status(), agent_hangup(), ast_do_masquerade(), ast_setstate(), attempt_transfer(), func_channel_read(), handle_chanlist(), handle_invite_replaces(), handle_showchan(), local_attended_transfer(), mgcp_new(), serialize_showchan(), and sip_hangup().

00658 {
00659    char *buf;
00660 
00661    switch (state) {
00662    case AST_STATE_DOWN:
00663       return "Down";
00664    case AST_STATE_RESERVED:
00665       return "Rsrvd";
00666    case AST_STATE_OFFHOOK:
00667       return "OffHook";
00668    case AST_STATE_DIALING:
00669       return "Dialing";
00670    case AST_STATE_RING:
00671       return "Ring";
00672    case AST_STATE_RINGING:
00673       return "Ringing";
00674    case AST_STATE_UP:
00675       return "Up";
00676    case AST_STATE_BUSY:
00677       return "Busy";
00678    case AST_STATE_DIALING_OFFHOOK:
00679       return "Dialing Offhook";
00680    case AST_STATE_PRERING:
00681       return "Pre-ring";
00682    default:
00683       if (!(buf = ast_threadstorage_get(&state2str_threadbuf, STATE2STR_BUFSIZE)))
00684          return "Unknown";
00685       snprintf(buf, STATE2STR_BUFSIZE, "Unknown (%d)", state);
00686       return buf;
00687    }
00688 }

int ast_str2cause ( const char *  name  ) 

Convert a symbolic hangup cause to number.

Convert the string form of a cause code to a number

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

Definition at line 643 of file channel.c.

References ARRAY_LEN, and causes.

Referenced by pbx_builtin_hangup().

00644 {
00645    int x;
00646 
00647    for (x = 0; x < ARRAY_LEN(causes); x++)
00648       if (!strncasecmp(causes[x].name, name, strlen(causes[x].name)))
00649          return causes[x].cause;
00650 
00651    return -1;
00652 }

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

Play a tone pair for a given amount of time

Definition at line 5439 of file channel.c.

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

Referenced by zapateller_exec().

05440 {
05441    int res;
05442 
05443    if ((res = ast_tonepair_start(chan, freq1, freq2, duration, vol)))
05444       return res;
05445 
05446    /* Give us some wiggle room */
05447    while (chan->generatordata && ast_waitfor(chan, 100) >= 0) {
05448       struct ast_frame *f = ast_read(chan);
05449       if (f)
05450          ast_frfree(f);
05451       else
05452          return -1;
05453    }
05454    return 0;
05455 }

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

Start a tone going

Definition at line 5421 of file channel.c.

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

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

05422 {
05423    struct tonepair_def d = { 0, };
05424 
05425    d.freq1 = freq1;
05426    d.freq2 = freq2;
05427    d.duration = duration;
05428    d.vol = (vol < 1) ? 8192 : vol; /* force invalid to 8192 */
05429    if (ast_activate_generator(chan, &tonepair, &d))
05430       return -1;
05431    return 0;
05432 }

void ast_tonepair_stop ( struct ast_channel chan  ) 

Stop a tone from playing

Definition at line 5434 of file channel.c.

References ast_deactivate_generator().

Referenced by sendnoise().

05435 {
05436    ast_deactivate_generator(chan);
05437 }

int ast_transfer ( struct ast_channel chan,
char *  dest 
)

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

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

Called by:

  • app_transfer
  • the manager interface

Definition at line 4042 of file channel.c.

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

Referenced by transfer_exec().

04043 {
04044    int res = -1;
04045 
04046    /* Stop if we're a zombie or need a soft hangup */
04047    ast_channel_lock(chan);
04048    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
04049       if (chan->tech->transfer) {
04050          res = chan->tech->transfer(chan, dest);
04051          if (!res)
04052             res = 1;
04053       } else
04054          res = 0;
04055    }
04056    ast_channel_unlock(chan);
04057    return res;
04058 }

char* ast_transfercapability2str ( int  transfercapability  )  const

Gives the string form of a given transfer capability.

Gives the string form of a given transfer capability

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

Definition at line 691 of file channel.c.

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

Referenced by cb_events(), dahdi_call(), dahdi_new(), misdn_call(), and oh323_call().

00692 {
00693    switch (transfercapability) {
00694    case AST_TRANS_CAP_SPEECH:
00695       return "SPEECH";
00696    case AST_TRANS_CAP_DIGITAL:
00697       return "DIGITAL";
00698    case AST_TRANS_CAP_RESTRICTED_DIGITAL:
00699       return "RESTRICTED_DIGITAL";
00700    case AST_TRANS_CAP_3_1K_AUDIO:
00701       return "3K1AUDIO";
00702    case AST_TRANS_CAP_DIGITAL_W_TONES:
00703       return "DIGITAL_W_TONES";
00704    case AST_TRANS_CAP_VIDEO:
00705       return "VIDEO";
00706    default:
00707       return "UNKNOWN";
00708    }
00709 }

void ast_uninstall_music_functions ( void   ) 

Definition at line 5502 of file channel.c.

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by unload_module().

05503 {
05504    ast_moh_start_ptr = NULL;
05505    ast_moh_stop_ptr = NULL;
05506    ast_moh_cleanup_ptr = NULL;
05507 }

int ast_waitfor ( struct ast_channel chan,
int  ms 
)

Wait for input on a channel.

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

Definition at line 2362 of file channel.c.

References ast_waitfor_nandfds().

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

02363 {
02364    int oldms = ms;   /* -1 if no timeout */
02365 
02366    ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
02367    if ((ms < 0) && (oldms < 0))
02368       ms = 0;
02369    return ms;
02370 }

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

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

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

Definition at line 2357 of file channel.c.

References ast_waitfor_nandfds().

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

02358 {
02359    return ast_waitfor_nandfds(c, n, NULL, 0, NULL, NULL, ms);
02360 }

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

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

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

Definition at line 2002 of file channel.c.

References ast_waitfor_nandfds().

Referenced by dundi_lookup_internal(), and dundi_precache_internal().

02003 {
02004    int winner = -1;
02005    ast_waitfor_nandfds(NULL, 0, fds, n, exception, &winner, ms);
02006    return winner;
02007 }

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

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

Waits for activity on a group of channels.

Definition at line 2014 of file channel.c.

References ast_channel::_softhangup, ast_add_fd(), ast_channel_lock, ast_channel_unlock, ast_clear_flag, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_EXCEPTION, ast_log(), AST_MAX_FDS, ast_poll, ast_set_flag, AST_SOFTHANGUP_TIMEOUT, ast_tvcmp(), ast_tvdiff_ms(), ast_tvnow(), ast_tvsub(), ast_tvzero(), CHECK_BLOCKING, errno, ast_channel::fdno, and LOG_WARNING.

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

02017 {
02018    struct timeval start = { 0 , 0 };
02019    struct pollfd *pfds = NULL;
02020    int res;
02021    long rms;
02022    int x, y, max;
02023    int sz;
02024    struct timeval now = { 0, 0 };
02025    struct timeval whentohangup = { 0, 0 }, diff;
02026    struct ast_channel *winner = NULL;
02027    struct fdmap {
02028       int chan;
02029       int fdno;
02030    } *fdmap = NULL;
02031 
02032    if ((sz = n * AST_MAX_FDS + nfds)) {
02033       pfds = alloca(sizeof(*pfds) * sz);
02034       fdmap = alloca(sizeof(*fdmap) * sz);
02035    }
02036 
02037    if (outfd)
02038       *outfd = -99999;
02039    if (exception)
02040       *exception = 0;
02041    
02042    /* Perform any pending masquerades */
02043    for (x = 0; x < n; x++) {
02044       ast_channel_lock(c[x]);
02045       if (c[x]->masq && ast_do_masquerade(c[x])) {
02046          ast_log(LOG_WARNING, "Masquerade failed\n");
02047          *ms = -1;
02048          ast_channel_unlock(c[x]);
02049          return NULL;
02050       }
02051       if (!ast_tvzero(c[x]->whentohangup)) {
02052          if (ast_tvzero(whentohangup))
02053             now = ast_tvnow();
02054          diff = ast_tvsub(c[x]->whentohangup, now);
02055          if (diff.tv_sec < 0 || ast_tvzero(diff)) {
02056             /* Should already be hungup */
02057             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
02058             ast_channel_unlock(c[x]);
02059             return c[x];
02060          }
02061          if (ast_tvzero(whentohangup) || ast_tvcmp(diff, whentohangup) < 0)
02062             whentohangup = diff;
02063       }
02064       ast_channel_unlock(c[x]);
02065    }
02066    /* Wait full interval */
02067    rms = *ms;
02068    if (!ast_tvzero(whentohangup)) {
02069       rms = whentohangup.tv_sec * 1000 + whentohangup.tv_usec / 1000;              /* timeout in milliseconds */
02070       if (*ms >= 0 && *ms < rms)    /* original *ms still smaller */
02071          rms =  *ms;
02072    }
02073    /*
02074     * Build the pollfd array, putting the channels' fds first,
02075     * followed by individual fds. Order is important because
02076     * individual fd's must have priority over channel fds.
02077     */
02078    max = 0;
02079    for (x = 0; x < n; x++) {
02080       for (y = 0; y < AST_MAX_FDS; y++) {
02081          fdmap[max].fdno = y;  /* fd y is linked to this pfds */
02082          fdmap[max].chan = x;  /* channel x is linked to this pfds */
02083          max += ast_add_fd(&pfds[max], c[x]->fds[y]);
02084       }
02085       CHECK_BLOCKING(c[x]);
02086    }
02087    /* Add the individual fds */
02088    for (x = 0; x < nfds; x++) {
02089       fdmap[max].chan = -1;
02090       max += ast_add_fd(&pfds[max], fds[x]);
02091    }
02092 
02093    if (*ms > 0)
02094       start = ast_tvnow();
02095    
02096    if (sizeof(int) == 4) { /* XXX fix timeout > 600000 on linux x86-32 */
02097       do {
02098          int kbrms = rms;
02099          if (kbrms > 600000)
02100             kbrms = 600000;
02101          res = ast_poll(pfds, max, kbrms);
02102          if (!res)
02103             rms -= kbrms;
02104       } while (!res && (rms > 0));
02105    } else {
02106       res = ast_poll(pfds, max, rms);
02107    }
02108    for (x = 0; x < n; x++)
02109       ast_clear_flag(c[x], AST_FLAG_BLOCKING);
02110    if (res < 0) { /* Simulate a timeout if we were interrupted */
02111       if (errno != EINTR)
02112          *ms = -1;
02113       return NULL;
02114    }
02115    if (!ast_tvzero(whentohangup)) {   /* if we have a timeout, check who expired */
02116       now = ast_tvnow();
02117       for (x = 0; x < n; x++) {
02118          if (!ast_tvzero(c[x]->whentohangup) && ast_tvcmp(c[x]->whentohangup, now) <= 0) {
02119             c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
02120             if (winner == NULL)
02121                winner = c[x];
02122          }
02123       }
02124    }
02125    if (res == 0) { /* no fd ready, reset timeout and done */
02126       *ms = 0; /* XXX use 0 since we may not have an exact timeout. */
02127       return winner;
02128    }
02129    /*
02130     * Then check if any channel or fd has a pending event.
02131     * Remember to check channels first and fds last, as they
02132     * must have priority on setting 'winner'
02133     */
02134    for (x = 0; x < max; x++) {
02135       res = pfds[x].revents;
02136       if (res == 0)
02137          continue;
02138       if (fdmap[x].chan >= 0) {  /* this is a channel */
02139          winner = c[fdmap[x].chan]; /* override previous winners */
02140          if (res & POLLPRI)
02141             ast_set_flag(winner, AST_FLAG_EXCEPTION);
02142          else
02143             ast_clear_flag(winner, AST_FLAG_EXCEPTION);
02144          winner->fdno = fdmap[x].fdno;
02145       } else {       /* this is an fd */
02146          if (outfd)
02147             *outfd = pfds[x].fd;
02148          if (exception)
02149             *exception = (res & POLLPRI) ? -1 : 0;
02150          winner = NULL;
02151       }
02152    }
02153    if (*ms > 0) {
02154       *ms -= ast_tvdiff_ms(ast_tvnow(), start);
02155       if (*ms < 0)
02156          *ms = 0;
02157    }
02158    return winner;
02159 }

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

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

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

Definition at line 2411 of file channel.c.

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

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

02412 {
02413    /* Stop if we're a zombie or need a soft hangup */
02414    if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
02415       return -1;
02416 
02417    /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */
02418    ast_set_flag(c, AST_FLAG_END_DTMF_ONLY);
02419 
02420    /* Wait for a digit, no more than ms milliseconds total. */
02421    
02422    while (ms) {
02423       struct ast_channel *rchan;
02424       int outfd=-1;
02425 
02426       errno = 0;
02427       rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
02428       
02429       if (!rchan && outfd < 0 && ms) {
02430          if (errno == 0 || errno == EINTR)
02431             continue;
02432          ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
02433          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02434          return -1;
02435       } else if (outfd > -1) {
02436          /* The FD we were watching has something waiting */
02437          ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n");
02438          ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02439          return 1;
02440       } else if (rchan) {
02441          int res;
02442          struct ast_frame *f = ast_read(c);
02443          if (!f)
02444             return -1;
02445 
02446          switch (f->frametype) {
02447          case AST_FRAME_DTMF_BEGIN:
02448             break;
02449          case AST_FRAME_DTMF_END:
02450             res = f->subclass;
02451             ast_frfree(f);
02452             ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02453             return res;
02454          case AST_FRAME_CONTROL:
02455             switch (f->subclass) {
02456             case AST_CONTROL_HANGUP:
02457                ast_frfree(f);
02458                ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02459                return -1;
02460             case AST_CONTROL_RINGING:
02461             case AST_CONTROL_ANSWER:
02462             case AST_CONTROL_SRCUPDATE:
02463                /* Unimportant */
02464                break;
02465             default:
02466                ast_log(LOG_WARNING, "Unexpected control subclass '%d'\n", f->subclass);
02467                break;
02468             }
02469             break;
02470          case AST_FRAME_VOICE:
02471             /* Write audio if appropriate */
02472             if (audiofd > -1) {
02473                if (write(audiofd, f->data.ptr, f->datalen) < 0) {
02474                   ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
02475                }
02476             }
02477          default:
02478             /* Ignore */
02479             break;
02480          }
02481          ast_frfree(f);
02482       }
02483    }
02484 
02485    ast_clear_flag(c, AST_FLAG_END_DTMF_ONLY);
02486 
02487    return 0; /* Time is up */
02488 }

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

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

Definition at line 1298 of file channel.c.

References channel_find_locked().

Referenced by next_channel().

01300 {
01301    return channel_find_locked(chan, NULL, 0, context, exten);
01302 }

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

Get next channel by name prefix and lock it.

Get channel by name or uniqueid prefix (locks channel).

Definition at line 1285 of file channel.c.

References channel_find_locked().

Referenced by my_ast_get_channel_by_name_locked(), next_channel(), and softhangup_exec().

01287 {
01288    return channel_find_locked(chan, name, namelen, NULL, NULL);
01289 }

int ast_write ( struct ast_channel chan,
struct ast_frame frame 
)

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

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

Todo:
XXX should return 0 maybe ?

Definition at line 3383 of file channel.c.

References ast_channel::_softhangup, AST_AUDIOHOOK_DIRECTION_WRITE, ast_audiohook_write_list(), ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_UNHOLD, ast_deactivate_generator(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_WRITE_INT, AST_FLAG_ZOMBIE, ast_format_rate(), AST_FORMAT_T140, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frame_dump(), AST_FRAME_HTML, AST_FRAME_IAX, AST_FRAME_MODEM, AST_FRAME_NULL, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_frisolate(), AST_LIST_NEXT, ast_log(), AST_MONITOR_RUNNING, ast_seekstream(), ast_senddigit_begin(), ast_senddigit_end(), AST_SOFTHANGUP_DEV, ast_test_flag, ast_translate(), ast_writestream(), ast_channel::audiohooks, calc_monitor_jump(), CHECK_BLOCKING, ast_frame::data, ast_frame::datalen, DEBUGCHAN_FLAG, f, ast_filestream::fmt, ast_format::format, ast_channel::fout, FRAMECOUNT_INC, ast_frame::frametype, ast_channel::generatordata, ast_channel_tech::indicate, ast_channel::insmpl, ast_frame::len, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, chanlist::next, ast_channel::outsmpl, ast_frame::ptr, ast_channel::rawwriteformat, ast_channel_monitor::read_stream, ast_frame::samples, SEEK_FORCECUR, send_dtmf_event(), ast_channel_tech::send_html, ast_channel_tech::send_text, ast_channel_monitor::state, ast_frame::subclass, ast_channel::tech, ast_channel_tech::write, ast_channel_monitor::write_stream, ast_channel_tech::write_text, ast_channel_tech::write_video, and ast_channel::writetrans.

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

03384 {
03385    int res = -1;
03386    struct ast_frame *f = NULL;
03387    int count = 0;
03388 
03389    /*Deadlock avoidance*/
03390    while(ast_channel_trylock(chan)) {
03391       /*cannot goto done since the channel is not locked*/
03392       if(count++ > 10) {
03393          ast_debug(1, "Deadlock avoided for write to channel '%s'\n", chan->name);
03394          return 0;
03395       }
03396       usleep(1);
03397    }
03398    /* Stop if we're a zombie or need a soft hangup */
03399    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
03400       goto done;
03401 
03402    /* Handle any pending masquerades */
03403    if (chan->masq && ast_do_masquerade(chan)) {
03404       ast_log(LOG_WARNING, "Failed to perform masquerade\n");
03405       goto done;
03406    }
03407    if (chan->masqr) {
03408       res = 0; /* XXX explain, why 0 ? */
03409       goto done;
03410    }
03411    if (chan->generatordata) {
03412       if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
03413          ast_deactivate_generator(chan);
03414       else {
03415          if (fr->frametype == AST_FRAME_DTMF_END) {
03416             /* There is a generator running while we're in the middle of a digit.
03417              * It's probably inband DTMF, so go ahead and pass it so it can
03418              * stop the generator */
03419             ast_clear_flag(chan, AST_FLAG_BLOCKING);
03420             ast_channel_unlock(chan);
03421             res = ast_senddigit_end(chan, fr->subclass, fr->len);
03422             ast_channel_lock(chan);
03423             CHECK_BLOCKING(chan);
03424          } else if (fr->frametype == AST_FRAME_CONTROL && fr->subclass == AST_CONTROL_UNHOLD) {
03425             /* This is a side case where Echo is basically being called and the person put themselves on hold and took themselves off hold */
03426             res = (chan->tech->indicate == NULL) ? 0 :
03427                chan->tech->indicate(chan, fr->subclass, fr->data.ptr, fr->datalen);
03428          }
03429          res = 0; /* XXX explain, why 0 ? */
03430          goto done;
03431       }
03432    }
03433    /* High bit prints debugging */
03434    if (chan->fout & DEBUGCHAN_FLAG)
03435       ast_frame_dump(chan->name, fr, ">>");
03436    CHECK_BLOCKING(chan);
03437    switch (fr->frametype) {
03438    case AST_FRAME_CONTROL:
03439       res = (chan->tech->indicate == NULL) ? 0 :
03440          chan->tech->indicate(chan, fr->subclass, fr->data.ptr, fr->datalen);
03441       break;
03442    case AST_FRAME_DTMF_BEGIN:
03443       if (chan->audiohooks) {
03444          struct ast_frame *old_frame = fr;
03445          fr = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
03446          if (old_frame != fr)
03447             f = fr;
03448       }
03449       send_dtmf_event(chan, "Sent", fr->subclass, "Yes", "No");
03450       ast_clear_flag(chan, AST_FLAG_BLOCKING);
03451       ast_channel_unlock(chan);
03452       res = ast_senddigit_begin(chan, fr->subclass);
03453       ast_channel_lock(chan);
03454       CHECK_BLOCKING(chan);
03455       break;
03456    case AST_FRAME_DTMF_END:
03457       if (chan->audiohooks) {
03458          struct ast_frame *new_frame = fr;
03459 
03460          new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, fr);
03461          if (new_frame != fr) {
03462             ast_frfree(new_frame);
03463          }
03464       }
03465       send_dtmf_event(chan, "Sent", fr->subclass, "No", "Yes");
03466       ast_clear_flag(chan, AST_FLAG_BLOCKING);
03467       ast_channel_unlock(chan);
03468       res = ast_senddigit_end(chan, fr->subclass, fr->len);
03469       ast_channel_lock(chan);
03470       CHECK_BLOCKING(chan);
03471       break;
03472    case AST_FRAME_TEXT:
03473       if (fr->subclass == AST_FORMAT_T140) {
03474          res = (chan->tech->write_text == NULL) ? 0 :
03475             chan->tech->write_text(chan, fr);
03476       } else {
03477          res = (chan->tech->send_text == NULL) ? 0 :
03478             chan->tech->send_text(chan, (char *) fr->data.ptr);
03479       }
03480       break;
03481    case AST_FRAME_HTML:
03482       res = (chan->tech->send_html == NULL) ? 0 :
03483          chan->tech->send_html(chan, fr->subclass, (char *) fr->data.ptr, fr->datalen);
03484       break;
03485    case AST_FRAME_VIDEO:
03486       /* XXX Handle translation of video codecs one day XXX */
03487       res = (chan->tech->write_video == NULL) ? 0 :
03488          chan->tech->write_video(chan, fr);
03489       break;
03490    case AST_FRAME_MODEM:
03491       res = (chan->tech->write == NULL) ? 0 :
03492          chan->tech->write(chan, fr);
03493       break;
03494    case AST_FRAME_VOICE:
03495       if (chan->tech->write == NULL)
03496          break;   /*! \todo XXX should return 0 maybe ? */
03497 
03498       /* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
03499       if (fr->subclass == chan->rawwriteformat)
03500          f = fr;
03501       else
03502          f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
03503 
03504       if (!f) {
03505          res = 0;
03506          break;
03507       }
03508 
03509       if (chan->audiohooks) {
03510          struct ast_frame *prev = NULL, *new_frame, *cur, *dup;
03511          int freeoldlist = 0;
03512 
03513          if (f != fr) {
03514             freeoldlist = 1;
03515          }
03516 
03517          /* Since ast_audiohook_write may return a new frame, and the cur frame is
03518           * an item in a list of frames, create a new list adding each cur frame back to it
03519           * regardless if the cur frame changes or not. */
03520          for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
03521             new_frame = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_WRITE, cur);
03522 
03523             /* if this frame is different than cur, preserve the end of the list,
03524              * free the old frames, and set cur to be the new frame */
03525             if (new_frame != cur) {
03526 
03527                /* doing an ast_frisolate here seems silly, but we are not guaranteed the new_frame
03528                 * isn't part of local storage, meaning if ast_audiohook_write is called multiple
03529                 * times it may override the previous frame we got from it unless we dup it */
03530                if ((dup = ast_frisolate(new_frame))) {
03531                   AST_LIST_NEXT(dup, frame_list) = AST_LIST_NEXT(cur, frame_list);
03532                   if (freeoldlist) {
03533                      AST_LIST_NEXT(cur, frame_list) = NULL;
03534                      ast_frfree(cur);
03535                   }
03536                   cur = dup;
03537                }
03538             }
03539 
03540             /* now, regardless if cur is new or not, add it to the new list,
03541              * if the new list has not started, cur will become the first item. */
03542             if (prev) {
03543                AST_LIST_NEXT(prev, frame_list) = cur;
03544             } else {
03545                f = cur; /* set f to be the beginning of our new list */
03546             }
03547             prev = cur;
03548          }
03549       }
03550       
03551       /* If Monitor is running on this channel, then we have to write frames out there too */
03552       /* the translator on chan->writetrans may have returned multiple frames
03553          from the single frame we passed in; if so, feed each one of them to the
03554          monitor */
03555       if (chan->monitor && chan->monitor->write_stream) {
03556          struct ast_frame *cur;
03557 
03558          for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
03559          /* XXX must explain this code */
03560 #ifndef MONITOR_CONSTANT_DELAY
03561             int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples;
03562             if (jump >= 0) {
03563                jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass), ast_format_rate(chan->monitor->read_stream->fmt->format));
03564                if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
03565                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
03566                chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples;
03567             } else {
03568                chan->outsmpl += cur->samples;
03569             }
03570 #else
03571             int jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass), ast_format_rate(chan->monitor->read_stream->fmt->format));
03572             if (jump - MONITOR_DELAY >= 0) {
03573                if (ast_seekstream(chan->monitor->write_stream, jump - cur->samples, SEEK_FORCECUR) == -1)
03574                   ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
03575                chan->outsmpl += chan->insmpl - chan->outsmpl;
03576             } else {
03577                chan->outsmpl += cur->samples;
03578             }
03579 #endif
03580             if (chan->monitor->state == AST_MONITOR_RUNNING) {
03581                if (ast_writestream(chan->monitor->write_stream, cur) < 0)
03582                   ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
03583             }
03584          }
03585       }
03586 
03587       /* the translator on chan->writetrans may have returned multiple frames
03588          from the single frame we passed in; if so, feed each one of them to the
03589          channel, freeing each one after it has been written */
03590       if ((f != fr) && AST_LIST_NEXT(f, frame_list)) {
03591          struct ast_frame *cur, *next;
03592          unsigned int skip = 0;
03593 
03594          for (cur = f, next = AST_LIST_NEXT(cur, frame_list);
03595               cur;
03596               cur = next, next = cur ? AST_LIST_NEXT(cur, frame_list) : NULL) {
03597             if (!skip) {
03598                if ((res = chan->tech->write(chan, cur)) < 0) {
03599                   chan->_softhangup |= AST_SOFTHANGUP_DEV;
03600                   skip = 1;
03601                } else if (next) {
03602                   /* don't do this for the last frame in the list,
03603                      as the code outside the loop will do it once
03604                   */
03605                   chan->fout = FRAMECOUNT_INC(chan->fout);
03606                }
03607             }
03608             ast_frfree(cur);
03609          }
03610 
03611          /* reset f so the code below doesn't attempt to free it */
03612          f = NULL;
03613       } else {
03614          res = chan->tech->write(chan, f);
03615       }
03616       break;
03617    case AST_FRAME_NULL:
03618    case AST_FRAME_IAX:
03619       /* Ignore these */
03620       res = 0;
03621       break;
03622    default:
03623       /* At this point, fr is the incoming frame and f is NULL.  Channels do
03624        * not expect to get NULL as a frame pointer and will segfault.  Hence,
03625        * we output the original frame passed in. */
03626       res = chan->tech->write(chan, fr);
03627       break;
03628    }
03629 
03630    if (f && f != fr)
03631       ast_frfree(f);
03632    ast_clear_flag(chan, AST_FLAG_BLOCKING);
03633 
03634    /* Consider a write failure to force a soft hangup */
03635    if (res < 0) {
03636       chan->_softhangup |= AST_SOFTHANGUP_DEV;
03637    } else {
03638       chan->fout = FRAMECOUNT_INC(chan->fout);
03639    }
03640 done:
03641    ast_channel_unlock(chan);
03642    return res;
03643 }

int ast_write_video ( struct ast_channel chan,
struct ast_frame frame 
)

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

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

Definition at line 3372 of file channel.c.

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

03373 {
03374    int res;
03375    if (!chan->tech->write_video)
03376       return 0;
03377    res = ast_write(chan, fr);
03378    if (!res)
03379       res = 1;
03380    return res;
03381 }

static void bridge_play_sounds ( struct ast_channel c0,
struct ast_channel c1 
) [static]

Definition at line 4999 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_strdupa, bridge_playfile(), pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and s.

Referenced by ast_channel_bridge().

05000 {
05001    const char *s, *sound;
05002 
05003    /* See if we need to play an audio file to any side of the bridge */
05004 
05005    ast_channel_lock(c0);
05006    if ((s = pbx_builtin_getvar_helper(c0, "BRIDGE_PLAY_SOUND"))) {
05007       sound = ast_strdupa(s);
05008       ast_channel_unlock(c0);
05009       bridge_playfile(c0, c1, sound, 0);
05010       pbx_builtin_setvar_helper(c0, "BRIDGE_PLAY_SOUND", NULL);
05011    } else {
05012       ast_channel_unlock(c0);
05013    }
05014 
05015    ast_channel_lock(c1);
05016    if ((s = pbx_builtin_getvar_helper(c1, "BRIDGE_PLAY_SOUND"))) {
05017       sound = ast_strdupa(s);
05018       ast_channel_unlock(c1);
05019       bridge_playfile(c1, c0, sound, 0);
05020       pbx_builtin_setvar_helper(c1, "BRIDGE_PLAY_SOUND", NULL);
05021    } else {
05022       ast_channel_unlock(c1);
05023    }
05024 }

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

Definition at line 4714 of file channel.c.

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

Referenced by ast_channel_bridge(), and bridge_play_sounds().

04715 {
04716    int min = 0, sec = 0, check;
04717 
04718    check = ast_autoservice_start(peer);
04719    if (check)
04720       return;
04721 
04722    if (remain > 0) {
04723       if (remain / 60 > 1) {
04724          min = remain / 60;
04725          sec = remain % 60;
04726       } else {
04727          sec = remain;
04728       }
04729    }
04730    
04731    if (!strcmp(sound,"timeleft")) { /* Queue support */
04732       ast_stream_and_wait(chan, "vm-youhave", "");
04733       if (min) {
04734          ast_say_number(chan, min, AST_DIGIT_ANY, chan->language, NULL);
04735          ast_stream_and_wait(chan, "queue-minutes", "");
04736       }
04737       if (sec) {
04738          ast_say_number(chan, sec, AST_DIGIT_ANY, chan->language, NULL);
04739          ast_stream_and_wait(chan, "queue-seconds", "");
04740       }
04741    } else {
04742       ast_stream_and_wait(chan, sound, "");
04743    }
04744 
04745    ast_autoservice_stop(peer);
04746 }

static int calc_monitor_jump ( int  samples,
int  sample_rate,
int  seek_rate 
) [inline, static]

calculates the number of samples to jump forward with in a monitor stream.

Note:
When using ast_seekstream() with the read and write streams of a monitor, the number of samples to seek forward must be of the same sample rate as the stream or else the jump will not be calculated correctly.
Return values:
number of samples to seek forward after rate conversion.

Definition at line 2596 of file channel.c.

Referenced by __ast_read(), and ast_write().

02597 {
02598    int diff = sample_rate - seek_rate;
02599 
02600    if (diff > 0) {
02601       samples = samples / (float) (sample_rate / seek_rate);
02602    } else if (diff < 0) {
02603       samples = samples * (float) (seek_rate / sample_rate);
02604    }
02605 
02606    return samples;
02607 }

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

Helper function to find channels.

It supports these modes:

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

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

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

Note:
We're done searching through the list for the previous item. Any item after this point, we want to evaluate for a match. If we didn't set prev to NULL here, then we would only return matches for the first matching item (since the above "if (c != prev)" would not permit any other potential matches to reach the additional matching logic, below). Instead, it would just iterate until it once again found the original match, then iterate down to the end of the list and quit.

Definition at line 1183 of file channel.c.

References ast_channel_trylock, ast_debug, AST_RWLIST_NEXT, AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, channels, ast_channel::context, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, and msg.

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

01186 {
01187    const char *msg = prev ? "deadlock" : "initial deadlock";
01188    int retries;
01189    struct ast_channel *c;
01190    const struct ast_channel *_prev = prev;
01191 
01192    for (retries = 0; retries < 200; retries++) {
01193       int done;
01194       /* Reset prev on each retry.  See note below for the reason. */
01195       prev = _prev;
01196       AST_RWLIST_RDLOCK(&channels);
01197       AST_RWLIST_TRAVERSE(&channels, c, chan_list) {
01198          if (prev) { /* look for last item, first, before any evaluation */
01199             if (c != prev) /* not this one */
01200                continue;
01201             /* found, prepare to return c->next */
01202             if ((c = AST_RWLIST_NEXT(c, chan_list)) == NULL) break;
01203             /*!\note
01204              * We're done searching through the list for the previous item.
01205              * Any item after this point, we want to evaluate for a match.
01206              * If we didn't set prev to NULL here, then we would only
01207              * return matches for the first matching item (since the above
01208              * "if (c != prev)" would not permit any other potential
01209              * matches to reach the additional matching logic, below).
01210              * Instead, it would just iterate until it once again found the
01211              * original match, then iterate down to the end of the list and
01212              * quit.
01213              */
01214             prev = NULL;
01215          }
01216          if (name) { /* want match by name */
01217             if ((!namelen && strcasecmp(c->name, name) && strcmp(c->uniqueid, name)) ||
01218                 (namelen && strncasecmp(c->name, name, namelen)))
01219                continue;   /* name match failed */
01220          } else if (exten) {
01221             if (context && strcasecmp(c->context, context) &&
01222                 strcasecmp(c->macrocontext, context))
01223                continue;   /* context match failed */
01224             if (strcasecmp(c->exten, exten) &&
01225                 strcasecmp(c->macroexten, exten))
01226                continue;   /* exten match failed */
01227          }
01228          /* if we get here, c points to the desired record */
01229          break;
01230       }
01231       /* exit if chan not found or mutex acquired successfully */
01232       /* this is slightly unsafe, as we _should_ hold the lock to access c->name */
01233       done = c == NULL || ast_channel_trylock(c) == 0;
01234       if (!done) {
01235          ast_debug(1, "Avoiding %s for channel '%p'\n", msg, c);
01236          if (retries == 199) {
01237             /* We are about to fail due to a deadlock, so report this
01238              * while we still have the list lock.
01239              */
01240             ast_debug(1, "Failure, could not lock '%p' after %d retries!\n", c, retries);
01241             /* As we have deadlocked, we will skip this channel and
01242              * see if there is another match.
01243              * NOTE: No point doing this for a full-name match,
01244              * as there can be no more matches.
01245              */
01246             if (!(name && !namelen)) {
01247                prev = c;
01248                retries = -1;
01249             }
01250          }
01251       }
01252       AST_RWLIST_UNLOCK(&channels);
01253       if (done)
01254          return c;
01255       /* If we reach this point we basically tried to lock a channel and failed. Instead of
01256        * starting from the beginning of the list we can restore our saved pointer to the previous
01257        * channel and start from there.
01258        */
01259       prev = _prev;
01260       usleep(1);  /* give other threads a chance before retrying */
01261    }
01262 
01263    return NULL;
01264 }

const char* channelreloadreason2txt ( enum channelreloadreason  reason  ) 

Convert enum channelreloadreason to text string for manager event.

\ brief Convert channel reloadreason (ENUM) to text string for manager event

Definition at line 5652 of file channel.c.

References CHANNEL_CLI_RELOAD, CHANNEL_MODULE_LOAD, and CHANNEL_MODULE_RELOAD.

Referenced by reload_config().

05653 {
05654    switch (reason) {
05655    case CHANNEL_MODULE_LOAD:
05656       return "LOAD (Channel module load)";
05657 
05658    case CHANNEL_MODULE_RELOAD:
05659       return "RELOAD (Channel module reload)";
05660 
05661    case CHANNEL_CLI_RELOAD:
05662       return "CLIRELOAD (Channel module reload by CLI command)";
05663 
05664    default:
05665       return "MANAGERRELOAD (Channel module reload by manager)";
05666    }
05667 };

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

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

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

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

Definition at line 4323 of file channel.c.

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

Referenced by ast_do_masquerade().

04324 {
04325    struct ast_var_t *current, *newvar;
04326    /* Append variables from clone channel into original channel */
04327    /* XXX Is this always correct?  We have to in order to keep MACROS working XXX */
04328    if (AST_LIST_FIRST(&clonechan->varshead))
04329       AST_LIST_APPEND_LIST(&original->varshead, &clonechan->varshead, entries);
04330 
04331    /* then, dup the varshead list into the clone */
04332    
04333    AST_LIST_TRAVERSE(&original->varshead, current, entries) {
04334       newvar = ast_var_assign(current->name, current->value);
04335       if (newvar)
04336          AST_LIST_INSERT_TAIL(&clonechan->varshead, newvar, entries);
04337    }
04338 }

static char* complete_channeltypes ( struct ast_cli_args a  )  [static]

Definition at line 246 of file channel.c.

References AST_LIST_TRAVERSE, ast_strdup, ast_cli_args::n, ast_cli_args::pos, chanlist::tech, ast_channel_tech::type, and ast_cli_args::word.

Referenced by handle_cli_core_show_channeltype().

00247 {
00248    struct chanlist *cl;
00249    int which = 0;
00250    int wordlen;
00251    char *ret = NULL;
00252 
00253    if (a->pos != 3)
00254       return NULL;
00255 
00256    wordlen = strlen(a->word);
00257 
00258    AST_LIST_TRAVERSE(&backends, cl, list) {
00259       if (!strncasecmp(a->word, cl->tech->type, wordlen) && ++which > a->n) {
00260          ret = ast_strdup(cl->tech->type);
00261          break;
00262       }
00263    }
00264    
00265    return ret;
00266 }

static void free_cid ( struct ast_callerid cid  )  [static]

Definition at line 1349 of file channel.c.

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

Referenced by ast_channel_free().

01350 {
01351    if (cid->cid_dnid)
01352       ast_free(cid->cid_dnid);
01353    if (cid->cid_num)
01354       ast_free(cid->cid_num); 
01355    if (cid->cid_name)
01356       ast_free(cid->cid_name);   
01357    if (cid->cid_ani)
01358       ast_free(cid->cid_ani);
01359    if (cid->cid_rdnis)
01360       ast_free(cid->cid_rdnis);
01361    cid->cid_dnid = cid->cid_num = cid->cid_name = cid->cid_ani = cid->cid_rdnis = NULL;
01362 }

static void free_translation ( struct ast_channel clonechan  )  [static]

Definition at line 1650 of file channel.c.

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

Referenced by ast_do_masquerade(), and ast_hangup().

01651 {
01652    if (clonechan->writetrans)
01653       ast_translator_free_path(clonechan->writetrans);
01654    if (clonechan->readtrans)
01655       ast_translator_free_path(clonechan->readtrans);
01656    clonechan->writetrans = NULL;
01657    clonechan->readtrans = NULL;
01658    clonechan->rawwriteformat = clonechan->nativeformats;
01659    clonechan->rawreadformat = clonechan->nativeformats;
01660 }

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

Definition at line 1944 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_deactivate_generator(), ast_debug, AST_FORMAT_AUDIO_MASK, ast_format_rate(), ast_generator::generate, ast_channel::generator, ast_channel::generatordata, and ast_channel::writeformat.

Referenced by ast_activate_generator(), and ast_read_generator_actions().

01945 {
01946    /* Called if generator doesn't have data */
01947    void *tmp;
01948    int res;
01949    int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = NULL;
01950    struct ast_channel *chan = (struct ast_channel *)data;
01951 
01952    ast_channel_lock(chan);
01953    tmp = chan->generatordata;
01954    chan->generatordata = NULL;
01955    if (chan->generator)
01956       generate = chan->generator->generate;
01957    ast_channel_unlock(chan);
01958 
01959    if (!tmp || !generate)
01960       return 0;
01961 
01962    res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50);
01963 
01964    chan->generatordata = tmp;
01965 
01966    if (res) {
01967       ast_debug(1, "Auto-deactivating generator\n");
01968       ast_deactivate_generator(chan);
01969    }
01970 
01971    return 0;
01972 }

static void handle_cause ( int  cause,
int *  outstate 
) [static]

Definition at line 3738 of file channel.c.

References AST_CAUSE_BUSY, AST_CAUSE_CONGESTION, AST_CONTROL_BUSY, and AST_CONTROL_CONGESTION.

Referenced by __ast_request_and_dial(), and ast_call_forward().

03739 {
03740    if (outstate) {
03741       /* compute error and return */
03742       if (cause == AST_CAUSE_BUSY)
03743          *outstate = AST_CONTROL_BUSY;
03744       else if (cause == AST_CAUSE_CONGESTION)
03745          *outstate = AST_CONTROL_CONGESTION;
03746       else
03747          *outstate = 0;
03748    }
03749 }

static char* handle_cli_core_show_channeltype ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show details about a channel driver - CLI command.

Definition at line 269 of file channel.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_cli(), AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, ast_channel_tech::capabilities, channels, CLI_FAILURE, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, complete_channeltypes(), ast_channel_tech::devicestate, ast_cli_args::fd, ast_channel_tech::indicate, ast_channel_tech::send_digit_begin, ast_channel_tech::send_digit_end, ast_channel_tech::send_html, ast_channel_tech::send_image, ast_channel_tech::send_text, chanlist::tech, ast_channel_tech::transfer, ast_channel_tech::type, and ast_cli_entry::usage.

00270 {
00271    struct chanlist *cl = NULL;
00272 
00273    switch (cmd) {
00274    case CLI_INIT:
00275       e->command = "core show channeltype";
00276       e->usage =
00277          "Usage: core show channeltype <name>\n"
00278          "  Show details about the specified channel type, <name>.\n";
00279       return NULL;
00280    case CLI_GENERATE:
00281       return complete_channeltypes(a);
00282    }
00283 
00284    if (a->argc != 4)
00285       return CLI_SHOWUSAGE;
00286    
00287    AST_RWLIST_RDLOCK(&channels);
00288 
00289    AST_LIST_TRAVERSE(&backends, cl, list) {
00290       if (!strncasecmp(cl->tech->type, a->argv[3], strlen(cl->tech->type)))
00291          break;
00292    }
00293 
00294 
00295    if (!cl) {
00296       ast_cli(a->fd, "\n%s is not a registered channel driver.\n", a->argv[3]);
00297       AST_RWLIST_UNLOCK(&channels);
00298       return CLI_FAILURE;
00299    }
00300 
00301    ast_cli(a->fd,
00302       "-- Info about channel driver: %s --\n"
00303       "  Device State: %s\n"
00304       "    Indication: %s\n"
00305       "     Transfer : %s\n"
00306       "  Capabilities: %d\n"
00307       "   Digit Begin: %s\n"
00308       "     Digit End: %s\n"
00309       "    Send HTML : %s\n"
00310       " Image Support: %s\n"
00311       "  Text Support: %s\n",
00312       cl->tech->type,
00313       (cl->tech->devicestate) ? "yes" : "no",
00314       (cl->tech->indicate) ? "yes" : "no",
00315       (cl->tech->transfer) ? "yes" : "no",
00316       (cl->tech->capabilities) ? cl->tech->capabilities : -1,
00317       (cl->tech->send_digit_begin) ? "yes" : "no",
00318       (cl->tech->send_digit_end) ? "yes" : "no",
00319       (cl->tech->send_html) ? "yes" : "no",
00320       (cl->tech->send_image) ? "yes" : "no",
00321       (cl->tech->send_text) ? "yes" : "no"
00322       
00323    );
00324 
00325    AST_RWLIST_UNLOCK(&channels);
00326    return CLI_SUCCESS;
00327 }

static char* handle_cli_core_show_channeltypes ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Show channel types - CLI command.

Definition at line 203 of file channel.c.

References ast_cli_args::argc, ast_cli(), AST_LIST_TRAVERSE, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK, channels, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_channel_tech::description, ast_channel_tech::devicestate, ast_cli_args::fd, FORMAT, ast_channel_tech::indicate, chanlist::tech, ast_channel_tech::transfer, ast_channel_tech::type, and ast_cli_entry::usage.

00204 {
00205 #define FORMAT  "%-10.10s  %-40.40s %-12.12s %-12.12s %-12.12s\n"
00206    struct chanlist *cl;
00207    int count_chan = 0;
00208 
00209    switch (cmd) {
00210    case CLI_INIT:
00211       e->command = "core show channeltypes";
00212       e->usage =
00213          "Usage: core show channeltypes\n"
00214          "       Lists available channel types registered in your\n"
00215          "       Asterisk server.\n";
00216       return NULL;
00217    case CLI_GENERATE:
00218       return NULL;
00219    }
00220 
00221    if (a->argc != 3)
00222       return CLI_SHOWUSAGE;
00223 
00224    ast_cli(a->fd, FORMAT, "Type", "Description",       "Devicestate", "Indications", "Transfer");
00225    ast_cli(a->fd, FORMAT, "----------", "-----------", "-----------", "-----------", "--------");
00226 
00227    AST_RWLIST_RDLOCK(&channels);
00228 
00229    AST_LIST_TRAVERSE(&backends, cl, list) {
00230       ast_cli(a->fd, FORMAT, cl->tech->type, cl->tech->description,
00231          (cl->tech->devicestate) ? "yes" : "no",
00232          (cl->tech->indicate) ? "yes" : "no",
00233          (cl->tech->transfer) ? "yes" : "no");
00234       count_chan++;
00235    }
00236 
00237    AST_RWLIST_UNLOCK(&channels);
00238 
00239    ast_cli(a->fd, "----------\n%d channel drivers registered.\n", count_chan);
00240 
00241    return CLI_SUCCESS;
00242 
00243 #undef FORMAT
00244 }

static int attribute_const is_visible_indication ( enum ast_control_frame_type  condition  )  [static]

Definition at line 3088 of file channel.c.

References _XXX_AST_CONTROL_T38, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_FLASH, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_OFFHOOK, AST_CONTROL_OPTION, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_RADIO_KEY, AST_CONTROL_RADIO_UNKEY, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, and AST_CONTROL_WINK.

Referenced by ast_indicate_data().

03089 {
03090    /* Don't include a default case here so that we get compiler warnings
03091     * when a new type is added. */
03092 
03093    switch (condition) {
03094    case AST_CONTROL_PROGRESS:
03095    case AST_CONTROL_PROCEEDING:
03096    case AST_CONTROL_VIDUPDATE:
03097    case AST_CONTROL_SRCUPDATE:
03098    case AST_CONTROL_RADIO_KEY:
03099    case AST_CONTROL_RADIO_UNKEY:
03100    case AST_CONTROL_OPTION:
03101    case AST_CONTROL_WINK:
03102    case AST_CONTROL_FLASH:
03103    case AST_CONTROL_OFFHOOK:
03104    case AST_CONTROL_TAKEOFFHOOK:
03105    case AST_CONTROL_ANSWER:
03106    case AST_CONTROL_HANGUP:
03107    case AST_CONTROL_T38_PARAMETERS:
03108    case _XXX_AST_CONTROL_T38:
03109       break;
03110 
03111    case AST_CONTROL_CONGESTION:
03112    case AST_CONTROL_BUSY:
03113    case AST_CONTROL_RINGING:
03114    case AST_CONTROL_RING:
03115    case AST_CONTROL_HOLD:
03116    case AST_CONTROL_UNHOLD:
03117       return 1;
03118    }
03119 
03120    return 0;
03121 }

static void manager_bridge_event ( int  onoff,
int  type,
struct ast_channel c0,
struct ast_channel c1 
) [static]

Send manager event for bridge link and unlink events.

Parameters:
onoff Link/Unlinked
type 1 for core, 2 for native
c0 first channel in bridge
c1 second channel in bridge

Definition at line 4944 of file channel.c.

References ast_channel::cid, ast_callerid::cid_num, EVENT_FLAG_CALL, manager_event, and S_OR.

Referenced by ast_channel_bridge().

04945 {
04946    manager_event(EVENT_FLAG_CALL, "Bridge",
04947          "Bridgestate: %s\r\n"
04948            "Bridgetype: %s\r\n"
04949             "Channel1: %s\r\n"
04950             "Channel2: %s\r\n"
04951             "Uniqueid1: %s\r\n"
04952             "Uniqueid2: %s\r\n"
04953             "CallerID1: %s\r\n"
04954             "CallerID2: %s\r\n",
04955          onoff ? "Link" : "Unlink",
04956          type == 1 ? "core" : "native",
04957          c0->name, c1->name, c0->uniqueid, c1->uniqueid, 
04958          S_OR(c0->cid.cid_num, ""), 
04959          S_OR(c1->cid.cid_num, ""));
04960 }

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

Definition at line 2551 of file channel.c.

References AST_FRAME_DTMF_END, ast_queue_frame(), ast_channel::dtmff, ast_frame::frametype, ast_frame::len, and ast_frame::subclass.

Referenced by __ast_read().

02552 {
02553    struct ast_frame *fr = &chan->dtmff;
02554 
02555    fr->frametype = AST_FRAME_DTMF_END;
02556    fr->subclass = f->subclass;
02557    fr->len = f->len;
02558 
02559    /* The only time this function will be called is for a frame that just came
02560     * out of the channel driver.  So, we want to stick it on the tail of the
02561     * readq. */
02562 
02563    ast_queue_frame(chan, fr);
02564 }

static void report_new_callerid ( const struct ast_channel chan  )  [static]
Precondition:
chan is locked

Definition at line 4343 of file channel.c.

References ast_describe_caller_presentation(), ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, EVENT_FLAG_CALL, manager_event, and S_OR.

Referenced by ast_do_masquerade(), and ast_set_callerid().

04344 {
04345    manager_event(EVENT_FLAG_CALL, "NewCallerid",
04346             "Channel: %s\r\n"
04347             "CallerIDNum: %s\r\n"
04348             "CallerIDName: %s\r\n"
04349             "Uniqueid: %s\r\n"
04350             "CID-CallingPres: %d (%s)\r\n",
04351             chan->name,
04352             S_OR(chan->cid.cid_num, ""),
04353             S_OR(chan->cid.cid_name, ""),
04354             chan->uniqueid,
04355             chan->cid.cid_pres,
04356             ast_describe_caller_presentation(chan->cid.cid_pres)
04357             );
04358 }

static void send_dtmf_event ( const struct ast_channel chan,
const char *  direction,
const char  digit,
const char *  begin,
const char *  end 
) [static]

Definition at line 2490 of file channel.c.

References EVENT_FLAG_DTMF, and manager_event.

Referenced by __ast_read(), and ast_write().

02491 {
02492    manager_event(EVENT_FLAG_DTMF,
02493          "DTMF",
02494          "Channel: %s\r\n"
02495          "Uniqueid: %s\r\n"
02496          "Digit: %c\r\n"
02497          "Direction: %s\r\n"
02498          "Begin: %s\r\n"
02499          "End: %s\r\n",
02500          chan->name, chan->uniqueid, digit, direction, begin, end);
02501 }

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

Definition at line 3645 of file channel.c.

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

Referenced by ast_set_read_format(), and ast_set_write_format().

03647 {
03648    int native;
03649    int res;
03650    char from[200], to[200];
03651    
03652    /* Make sure we only consider audio */
03653    fmt &= AST_FORMAT_AUDIO_MASK;
03654    
03655    native = chan->nativeformats;
03656 
03657    if (!fmt || !native) /* No audio requested */
03658       return 0;   /* Let's try a call without any sounds (video, text) */
03659    
03660    /* Find a translation path from the native format to one of the desired formats */
03661    if (!direction)
03662       /* reading */
03663       res = ast_translator_best_choice(&fmt, &native);
03664    else
03665       /* writing */
03666       res = ast_translator_best_choice(&native, &fmt);
03667 
03668    if (res < 0) {
03669       ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
03670          ast_getformatname_multiple(from, sizeof(from), native),
03671          ast_getformatname_multiple(to, sizeof(to), fmt));
03672       return -1;
03673    }
03674    
03675    /* Now we have a good choice for both. */
03676    ast_channel_lock(chan);
03677 
03678    if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
03679       /* the channel is already in these formats, so nothing to do */
03680       ast_channel_unlock(chan);
03681       return 0;
03682    }
03683 
03684    *rawformat = native;
03685    /* User perspective is fmt */
03686    *format = fmt;
03687    /* Free any read translation we have right now */
03688    if (*trans)
03689       ast_translator_free_path(*trans);
03690    /* Build a translation path from the raw format to the desired format */
03691    if (!direction)
03692       /* reading */
03693       *trans = ast_translator_build_path(*format, *rawformat);
03694    else
03695       /* writing */
03696       *trans = ast_translator_build_path(*rawformat, *format);
03697    ast_channel_unlock(chan);
03698    ast_debug(1, "Set channel %s to %s format %s\n", chan->name,
03699       direction ? "write" : "read", ast_getformatname(fmt));
03700    return 0;
03701 }

static int should_skip_dtmf ( struct ast_channel chan  )  [inline, static]

Determine whether or not we should ignore DTMF in the readq.

Definition at line 2569 of file channel.c.

References AST_FLAG_DEFER_DTMF, AST_FLAG_EMULATE_DTMF, AST_MIN_DTMF_GAP, ast_test_flag, ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and ast_channel::dtmf_tv.

Referenced by __ast_read().

02570 {
02571    if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_EMULATE_DTMF)) {
02572       /* We're in the middle of emulating a digit, or DTMF has been
02573        * explicitly deferred.  Skip this digit, then. */
02574       return 1;
02575    }
02576          
02577    if (!ast_tvzero(chan->dtmf_tv) && 
02578          ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
02579       /* We're not in the middle of a digit, but it hasn't been long enough
02580        * since the last digit, so we'll have to skip DTMF for now. */
02581       return 1;
02582    }
02583 
02584    return 0;
02585 }

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

Definition at line 5572 of file channel.c.

05573 {
05574    /* just store the data pointer in the channel structure */
05575    return data;
05576 }

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

Definition at line 5583 of file channel.c.

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

05584 {
05585    short buf[samples];
05586    struct ast_frame frame = {
05587       .frametype = AST_FRAME_VOICE,
05588       .subclass = AST_FORMAT_SLINEAR,
05589       .data.ptr = buf,
05590       .samples = samples,
05591       .datalen = sizeof(buf),
05592    };
05593 
05594    memset(buf, 0, sizeof(buf));
05595 
05596    if (ast_write(chan, &frame))
05597       return -1;
05598 
05599    return 0;
05600 }

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

Definition at line 5578 of file channel.c.

05579 {
05580    /* nothing to do */
05581 }

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

Definition at line 5339 of file channel.c.

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

05340 {
05341    struct tonepair_state *ts;
05342    struct tonepair_def *td = params;
05343 
05344    if (!(ts = ast_calloc(1, sizeof(*ts))))
05345       return NULL;
05346    ts->origwfmt = chan->writeformat;
05347    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
05348       ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
05349       tonepair_release(NULL, ts);
05350       ts = NULL;
05351    } else {
05352       ts->fac1 = 2.0 * cos(2.0 * M_PI * (td->freq1 / 8000.0)) * 32768.0;
05353       ts->v1_1 = 0;
05354       ts->v2_1 = sin(-4.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
05355       ts->v3_1 = sin(-2.0 * M_PI * (td->freq1 / 8000.0)) * td->vol;
05356       ts->v2_1 = 0;
05357       ts->fac2 = 2.0 * cos(2.0 * M_PI * (td->freq2 / 8000.0)) * 32768.0;
05358       ts->v2_2 = sin(-4.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
05359       ts->v3_2 = sin(-2.0 * M_PI * (td->freq2 / 8000.0)) * td->vol;
05360       ts->duration = td->duration;
05361       ts->modulate = 0;
05362    }
05363    /* Let interrupts interrupt :) */
05364    ast_set_flag(chan, AST_FLAG_WRITE_INT);
05365    return ts;
05366 }

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

Definition at line 5368 of file channel.c.

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

05369 {
05370    struct tonepair_state *ts = data;
05371    int x;
05372 
05373    /* we need to prepare a frame with 16 * timelen samples as we're
05374     * generating SLIN audio
05375     */
05376    len = samples * 2;
05377 
05378    if (len > sizeof(ts->data) / 2 - 1) {
05379       ast_log(LOG_WARNING, "Can't generate that much data!\n");
05380       return -1;
05381    }
05382    memset(&ts->f, 0, sizeof(ts->f));
05383    for (x=0;x<len/2;x++) {
05384       ts->v1_1 = ts->v2_1;
05385       ts->v2_1 = ts->v3_1;
05386       ts->v3_1 = (ts->fac1 * ts->v2_1 >> 15) - ts->v1_1;
05387       
05388       ts->v1_2 = ts->v2_2;
05389       ts->v2_2 = ts->v3_2;
05390       ts->v3_2 = (ts->fac2 * ts->v2_2 >> 15) - ts->v1_2;
05391       if (ts->modulate) {
05392          int p;
05393          p = ts->v3_2 - 32768;
05394          if (p < 0) p = -p;
05395          p = ((p * 9) / 10) + 1;
05396          ts->data[x] = (ts->v3_1 * p) >> 15;
05397       } else
05398          ts->data[x] = ts->v3_1 + ts->v3_2; 
05399    }
05400    ts->f.frametype = AST_FRAME_VOICE;
05401    ts->f.subclass = AST_FORMAT_SLINEAR;
05402    ts->f.datalen = len;
05403    ts->f.samples = samples;
05404    ts->f.offset = AST_FRIENDLY_OFFSET;
05405    ts->f.data.ptr = ts->data;
05406    ast_write(chan, &ts->f);
05407    ts->pos += x;
05408    if (ts->duration > 0) {
05409       if (ts->pos >= ts->duration * 8)
05410          return -1;
05411    }
05412    return 0;
05413 }

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

Definition at line 5330 of file channel.c.

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

Referenced by tonepair_alloc().

05331 {
05332    struct tonepair_state *ts = params;
05333 
05334    if (chan)
05335       ast_set_write_format(chan, ts->origwfmt);
05336    ast_free(ts);
05337 }

static void update_bridge_vars ( struct ast_channel c0,
struct ast_channel c1 
) [static]

Definition at line 4962 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_strdupa, ast_strlen_zero(), ast_channel_tech::get_pvt_uniqueid, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), and ast_channel::tech.

Referenced by ast_channel_bridge().

04963 {
04964    const char *c0_name;
04965    const char *c1_name;
04966    const char *c0_pvtid = NULL;
04967    const char *c1_pvtid = NULL;
04968 
04969    ast_channel_lock(c1);
04970    c1_name = ast_strdupa(c1->name);
04971    if (c1->tech->get_pvt_uniqueid) {
04972       c1_pvtid = ast_strdupa(c1->tech->get_pvt_uniqueid(c1));
04973    }
04974    ast_channel_unlock(c1);
04975 
04976    ast_channel_lock(c0);
04977    if (!ast_strlen_zero(pbx_builtin_getvar_helper(c0, "BRIDGEPEER"))) {
04978       pbx_builtin_setvar_helper(c0, "BRIDGEPEER", c1_name);
04979    }
04980    if (c1_pvtid) {
04981       pbx_builtin_setvar_helper(c0, "BRIDGEPVTCALLID", c1_pvtid);
04982    }
04983    c0_name = ast_strdupa(c0->name);
04984    if (c0->tech->get_pvt_uniqueid) {
04985       c0_pvtid = ast_strdupa(c0->tech->get_pvt_uniqueid(c0));
04986    }
04987    ast_channel_unlock(c0);
04988 
04989    ast_channel_lock(c1);
04990    if (!ast_strlen_zero(pbx_builtin_getvar_helper(c1, "BRIDGEPEER"))) {
04991       pbx_builtin_setvar_helper(c1, "BRIDGEPEER", c0_name);
04992    }
04993    if (c0_pvtid) {
04994       pbx_builtin_setvar_helper(c1, "BRIDGEPVTCALLID", c0_pvtid);
04995    }
04996    ast_channel_unlock(c1);
04997 }


Variable Documentation

void(* ast_moh_cleanup_ptr)(struct ast_channel *) = NULL [static]
int(* ast_moh_start_ptr)(struct ast_channel *, const char *, const char *) = NULL [static]
void(* ast_moh_stop_ptr)(struct ast_channel *) = NULL [static]
struct ast_cause causes[]

map AST_CAUSE's to readable string representations

causes.h

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

struct ast_cli_entry cli_channel[] [static]
Initial value:
 {
   AST_CLI_DEFINE(handle_cli_core_show_channeltypes, "List available channel types"),

}

Definition at line 329 of file channel.c.

Referenced by ast_channels_init().

unsigned long global_fin

The current value of the debug flags is stored in the two variables global_fin and global_fout (declared in main/channel.c)

Definition at line 86 of file channel.c.

Referenced by handle_core_set_debug_channel().

unsigned long global_fout

Definition at line 86 of file channel.c.

Referenced by handle_core_set_debug_channel().

struct ast_channel_tech null_tech [static]
Initial value:
 {
   .type = "NULL",
   .description = "Null channel (should not see this)",
}

Definition at line 764 of file channel.c.

Referenced by __ast_channel_alloc_ap().

int shutting_down [static]

Prevent new channel allocation if shutting down.

Definition at line 82 of file channel.c.

Initial value:

Definition at line 5602 of file channel.c.

struct ast_generator tonepair [static]
Initial value:
 {
   alloc: tonepair_alloc,
   release: tonepair_release,
   generate: tonepair_generator,
}

Definition at line 5415 of file channel.c.

Referenced by ast_tonepair_start().

int uniqueint [static]

Definition at line 84 of file channel.c.


Generated on 8 Apr 2010 for Asterisk - the Open Source PBX by  doxygen 1.6.1