Wed Oct 28 13:32:20 2009

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/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/cel.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 "asterisk/autochan.h"
#include "asterisk/stringfields.h"

Include dependency graph for channel.c:

Go to the source code of this file.

Data Structures

struct  ast_channel_iterator
struct  ast_epoll_data
struct  ast_silence_generator
struct  backends
 the list of registered channel types More...
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 NUM_CHANNEL_BUCKETS   1567
#define STATE2STR_BUFSIZE   32

Enumerations

enum  {
  AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NUMBER_TYPE, AST_CONNECTED_LINE_NUMBER_PRESENTATION,
  AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN,
  AST_CONNECTED_LINE_SUBADDRESS_VALID
}
 Element identifiers for connected line indication frame data. More...
enum  {
  AST_REDIRECTING_FROM_NUMBER, AST_REDIRECTING_FROM_NAME, AST_REDIRECTING_FROM_NUMBER_TYPE, AST_REDIRECTING_FROM_NUMBER_PRESENTATION,
  AST_REDIRECTING_TO_NUMBER, AST_REDIRECTING_TO_NAME, AST_REDIRECTING_TO_NUMBER_TYPE, AST_REDIRECTING_TO_NUMBER_PRESENTATION,
  AST_REDIRECTING_REASON, AST_REDIRECTING_COUNT, AST_REDIRECTING_FROM_SUBADDRESS, AST_REDIRECTING_FROM_SUBADDRESS_TYPE,
  AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_FROM_SUBADDRESS_VALID, AST_REDIRECTING_TO_SUBADDRESS, AST_REDIRECTING_TO_SUBADDRESS_TYPE,
  AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, AST_REDIRECTING_TO_SUBADDRESS_VALID
}
 Element identifiers for redirecting indication frame data. More...

Functions

int __ast_answer (struct ast_channel *chan, unsigned int delay, int cdr_answer)
 Answer a channel, with a selectable delay before returning.
static void __ast_change_name_nolink (struct ast_channel *chan, const char *newname)
 this function simply changes the name of the channel and issues a manager_event with out unlinking and linking the channel from the ao2_container. This should only be used when the channel has already been unlinked from the ao2_container.
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 char *linkedid, 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 char *linkedid, 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, const struct ast_channel *requestor, 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.
static void __fini_backends (void)
static void __init_backends (void)
static void __init_state2str_threadbuf (void)
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)
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, const 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 char *linkedid, 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.
struct ast_channelast_channel_callback (ao2_callback_data_fn *cb_fn, void *arg, void *data, int ao2_flags)
 Call a function with every active channel.
static void ast_channel_change_linkedid (struct ast_channel *chan, const char *linkedid)
static int ast_channel_cmp_cb (void *obj, void *arg, int flags)
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_connected_line_macro (struct ast_channel *autoservice_chan, struct ast_channel *macro_chan, const void *connected_info, int caller, int frame)
 Run a connected line interception macro and update a channel's connected line information.
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.
static void ast_channel_destructor (void *obj)
 Free a channel structure.
int ast_channel_early_bridge (struct ast_channel *c0, struct ast_channel *c1)
 Bridge two channels together (early).
struct ast_channelast_channel_get_by_exten (const char *exten, const char *context)
 Find a channel by extension and context.
struct ast_channelast_channel_get_by_name (const char *name)
 Find a channel by name.
struct ast_channelast_channel_get_by_name_prefix (const char *name, size_t name_len)
 Find a channel by a name prefix.
static struct ast_channelast_channel_get_full (const char *name, size_t name_len, const char *exten, const char *context)
static int ast_channel_hash_cb (const void *obj, const int flags)
void ast_channel_inherit_variables (const struct ast_channel *parent, struct ast_channel *child)
 Inherits channel variable from parent to child channel.
struct ast_channel_iteratorast_channel_iterator_all_new (void)
 Create a new channel iterator.
struct ast_channel_iteratorast_channel_iterator_by_exten_new (const char *exten, const char *context)
 Create a new channel iterator based on extension.
struct ast_channel_iteratorast_channel_iterator_by_name_new (const char *name, size_t name_len)
 Create a new channel iterator based on name.
struct ast_channel_iteratorast_channel_iterator_destroy (struct ast_channel_iterator *i)
 Destroy a channel iterator.
struct ast_channelast_channel_iterator_next (struct ast_channel_iterator *i)
 Get the next channel for a channel iterator.
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)
 Checks the value of an option.
void ast_channel_queue_connected_line_update (struct ast_channel *chan, const struct ast_party_connected_line *connected)
 Queue a connected line update frame on a channel.
void ast_channel_queue_redirecting_update (struct ast_channel *chan, const struct ast_party_redirecting *redirecting)
 Queue a redirecting update frame on a channel.
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.
struct ast_channelast_channel_release (struct ast_channel *chan)
 Unlink and release reference to a channel.
int ast_channel_sendhtml (struct ast_channel *chan, int subclass, const char *data, int datalen)
 Sends HTML on given channel Send HTML or URL on link.
int ast_channel_sendurl (struct ast_channel *chan, const char *url)
 Sends a URL on a given link Send URL on link.
void ast_channel_set_connected_line (struct ast_channel *chan, const struct ast_party_connected_line *connected)
 Set the connected line information in the Asterisk channel.
void ast_channel_set_fd (struct ast_channel *chan, int which, int fd)
void ast_channel_set_linkgroup (struct ast_channel *chan, struct ast_channel *peer)
 Propagate the oldest linkedid between associated channels.
void ast_channel_set_redirecting (struct ast_channel *chan, const struct ast_party_redirecting *redirecting)
 Set the redirecting id information in the Asterisk channel.
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.
static int ast_channel_softhangup_cb (void *obj, void *arg, int flags)
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)
 Checks for HTML support on a channel.
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.
void ast_channel_update_connected_line (struct ast_channel *chan, const struct ast_party_connected_line *connected)
 Indicate that the connected line information has changed.
void ast_channel_update_redirecting (struct ast_channel *chan, const struct ast_party_redirecting *redirecting)
 Indicate that the redirecting id has changed.
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.
int ast_check_hangup_locked (struct ast_channel *chan)
int ast_connected_line_build_data (unsigned char *data, size_t datalen, const struct ast_party_connected_line *connected)
 Build the connected line information data frame.
void ast_connected_line_copy_from_caller (struct ast_party_connected_line *dest, const struct ast_callerid *src)
 Copy the caller information to the connected line information.
void ast_connected_line_copy_to_caller (struct ast_callerid *dest, const struct ast_party_connected_line *src)
 Copy the connected line information to the caller information.
int ast_connected_line_parse_data (const unsigned char *data, size_t datalen, struct ast_party_connected_line *connected)
 Parse connected line indication frame data.
void ast_deactivate_generator (struct ast_channel *chan)
int ast_do_masquerade (struct ast_channel *original)
 Masquerade a channel.
struct ast_channelast_dummy_channel_alloc (void)
 Create a fake channel structure.
static void ast_dummy_channel_destructor (void *obj)
 Free a dummy channel structure.
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 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.
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_party_caller_copy (struct ast_callerid *dest, const struct ast_callerid *src)
 Copy the source caller information to the destination caller.
void ast_party_caller_init (struct ast_party_caller *init)
 Initialize the given caller structure.
void ast_party_connected_line_collect_caller (struct ast_party_connected_line *connected, struct ast_callerid *cid)
 Collect the caller party information into a connected line structure.
void ast_party_connected_line_copy (struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
 Copy the source connected line information to the destination connected line.
void ast_party_connected_line_free (struct ast_party_connected_line *doomed)
 Destroy the connected line information contents.
void ast_party_connected_line_init (struct ast_party_connected_line *init)
 Initialize the given connected line structure.
void ast_party_connected_line_set (struct ast_party_connected_line *dest, const struct ast_party_connected_line *src)
 Set the connected line information based on another connected line source.
void ast_party_connected_line_set_init (struct ast_party_connected_line *init, const struct ast_party_connected_line *guide)
 Initialize the given connected line structure using the given guide for a set update operation.
static void ast_party_id_copy (struct ast_party_id *dest, const struct ast_party_id *src)
static void ast_party_id_free (struct ast_party_id *doomed)
static void ast_party_id_init (struct ast_party_id *init)
static void ast_party_id_set (struct ast_party_id *dest, const struct ast_party_id *src)
static void ast_party_id_set_init (struct ast_party_id *init, const struct ast_party_id *guide)
void ast_party_redirecting_copy (struct ast_party_redirecting *dest, const struct ast_party_redirecting *src)
 Copy the source redirecting information to the destination redirecting.
void ast_party_redirecting_free (struct ast_party_redirecting *doomed)
 Destroy the redirecting information contents.
void ast_party_redirecting_set_init (struct ast_party_redirecting *init, const struct ast_party_redirecting *guide)
 Initialize the given redirecting id structure using the given guide for a set update operation.
void ast_party_subaddress_copy (struct ast_party_subaddress *dest, const struct ast_party_subaddress *src)
 Copy the source party subaddress information to the destination party subaddress.
void ast_party_subaddress_free (struct ast_party_subaddress *doomed)
 Destroy the party subaddress contents.
void ast_party_subaddress_init (struct ast_party_subaddress *init)
 Initialize the given subaddress structure.
void ast_party_subaddress_set (struct ast_party_subaddress *dest, const struct ast_party_subaddress *src)
 Set the source party subaddress information into the destination party subaddress.
void ast_party_subaddress_set_init (struct ast_party_subaddress *init, const struct ast_party_subaddress *guide)
 Initialize the given party subadress structure using the given guide for a set update operation.
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)
 Reads multiple digits.
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.
int ast_redirecting_build_data (unsigned char *data, size_t datalen, const struct ast_party_redirecting *redirecting)
 Build the redirecting id data frame.
int ast_redirecting_parse_data (const unsigned char *data, size_t datalen, struct ast_party_redirecting *redirecting)
 Parse redirecting indication frame data.
struct ast_channelast_request (const char *type, int format, const struct ast_channel *requestor, void *data, int *cause)
 Requests a channel.
struct ast_channelast_request_and_dial (const char *type, int format, const struct ast_channel *requestor, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
 Request a channel of a given type, with data as optional information used by the low level module and attempt to place a call on it.
int ast_safe_sleep (struct ast_channel *chan, int ms)
 Wait, 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)
 says digits of a string
int ast_say_digits (struct ast_channel *chan, int num, const char *ints, const char *lang)
 says digits
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)
 says an enumeration
int ast_say_number (struct ast_channel *chan, int num, const char *ints, const char *language, const char *options)
 says a number
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.
int ast_senddigit_begin (struct ast_channel *chan, char digit)
 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.
void ast_set_hangupsource (struct ast_channel *chan, const char *source, int force)
 Set the source of the hangup in this channel and it's bridge.
static void ast_set_owners_and_peers (struct ast_channel *chan1, struct ast_channel *chan2)
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.
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.
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 struct
ast_channel_iterator
channel_iterator_search (const char *name, size_t name_len, const char *exten, const char *context)
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 const char * oldest_linkedid (const char *a, const char *b)
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 {
   int   cause
   const char *   desc
   const char *   name
causes []
 map AST_CAUSE's to readable string representations
static struct ao2_containerchannels
 All active channels on the system.
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_threadstorage state2str_threadbuf = { .once = PTHREAD_ONCE_INIT, .key_init = __init_state2str_threadbuf , .custom_init = NULL , }
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 95 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 98 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 102 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 NUM_CHANNEL_BUCKETS   1567

Definition at line 132 of file channel.c.

Referenced by ast_channels_init().

#define STATE2STR_BUFSIZE   32

Definition at line 91 of file channel.c.

Referenced by ast_state2str().


Enumeration Type Documentation

anonymous enum

Element identifiers for connected line indication frame data.

Note:
Only add to the end of this enum.
Enumerator:
AST_CONNECTED_LINE_NUMBER 
AST_CONNECTED_LINE_NAME 
AST_CONNECTED_LINE_NUMBER_TYPE 
AST_CONNECTED_LINE_NUMBER_PRESENTATION 
AST_CONNECTED_LINE_SOURCE 
AST_CONNECTED_LINE_SUBADDRESS 
AST_CONNECTED_LINE_SUBADDRESS_TYPE 
AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN 
AST_CONNECTED_LINE_SUBADDRESS_VALID 

Definition at line 6659 of file channel.c.

anonymous enum

Element identifiers for redirecting indication frame data.

Note:
Only add to the end of this enum.
Enumerator:
AST_REDIRECTING_FROM_NUMBER 
AST_REDIRECTING_FROM_NAME 
AST_REDIRECTING_FROM_NUMBER_TYPE 
AST_REDIRECTING_FROM_NUMBER_PRESENTATION 
AST_REDIRECTING_TO_NUMBER 
AST_REDIRECTING_TO_NAME 
AST_REDIRECTING_TO_NUMBER_TYPE 
AST_REDIRECTING_TO_NUMBER_PRESENTATION 
AST_REDIRECTING_REASON 
AST_REDIRECTING_COUNT 
AST_REDIRECTING_FROM_SUBADDRESS 
AST_REDIRECTING_FROM_SUBADDRESS_TYPE 
AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN 
AST_REDIRECTING_FROM_SUBADDRESS_VALID 
AST_REDIRECTING_TO_SUBADDRESS 
AST_REDIRECTING_TO_SUBADDRESS_TYPE 
AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN 
AST_REDIRECTING_TO_SUBADDRESS_VALID 

Definition at line 6942 of file channel.c.


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 2314 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, ast_frame::frame_list, frames, ast_frame::frametype, LOG_WARNING, MAX, ast_channel::name, and ast_frame::subclass.

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

02315 {
02316    int res = 0;
02317    enum ast_channel_state old_state;
02318 
02319    old_state = chan->_state;
02320    if ((res = ast_raw_answer(chan, cdr_answer))) {
02321       return res;
02322    }
02323 
02324    switch (old_state) {
02325    case AST_STATE_RINGING:
02326    case AST_STATE_RING:
02327       /* wait for media to start flowing, but don't wait any longer
02328        * than 'delay' or 500 milliseconds, whichever is longer
02329        */
02330       do {
02331          AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
02332          struct ast_frame *cur, *new;
02333          int ms = MAX(delay, 500);
02334          unsigned int done = 0;
02335 
02336          AST_LIST_HEAD_INIT_NOLOCK(&frames);
02337 
02338          for (;;) {
02339             ms = ast_waitfor(chan, ms);
02340             if (ms < 0) {
02341                ast_log(LOG_WARNING, "Error condition occurred when polling channel %s for a voice frame: %s\n", chan->name, strerror(errno));
02342                res = -1;
02343                break;
02344             }
02345             if (ms == 0) {
02346                ast_debug(2, "Didn't receive a media frame from %s within %d ms of answering. Continuing anyway\n", chan->name, MAX(delay, 500));
02347                break;
02348             }
02349             cur = ast_read(chan);
02350             if (!cur || ((cur->frametype == AST_FRAME_CONTROL) &&
02351                     (cur->subclass == AST_CONTROL_HANGUP))) {
02352                if (cur) {
02353                   ast_frfree(cur);
02354                }
02355                res = -1;
02356                ast_debug(2, "Hangup of channel %s detected in answer routine\n", chan->name);
02357                break;
02358             }
02359 
02360             if ((new = ast_frisolate(cur)) != cur) {
02361                ast_frfree(cur);
02362             }
02363 
02364             AST_LIST_INSERT_HEAD(&frames, new, frame_list);
02365 
02366             /* if a specific delay period was requested, continue
02367              * until that delay has passed. don't stop just because
02368              * incoming media has arrived.
02369              */
02370             if (delay) {
02371                continue;
02372             }
02373 
02374             switch (new->frametype) {
02375                /* all of these frametypes qualify as 'media' */
02376             case AST_FRAME_VOICE:
02377             case AST_FRAME_VIDEO:
02378             case AST_FRAME_TEXT:
02379             case AST_FRAME_DTMF_BEGIN:
02380             case AST_FRAME_DTMF_END:
02381             case AST_FRAME_IMAGE:
02382             case AST_FRAME_HTML:
02383             case AST_FRAME_MODEM:
02384                done = 1;
02385                break;
02386             case AST_FRAME_CONTROL:
02387             case AST_FRAME_IAX:
02388             case AST_FRAME_NULL:
02389             case AST_FRAME_CNG:
02390                break;
02391             }
02392 
02393             if (done) {
02394                break;
02395             }
02396          }
02397 
02398          if (res == 0) {
02399             ast_channel_lock(chan);
02400             while ((cur = AST_LIST_REMOVE_HEAD(&frames, frame_list))) {
02401                ast_queue_frame_head(chan, cur);
02402                ast_frfree(cur);
02403             }
02404             ast_channel_unlock(chan);
02405          }
02406       } while (0);
02407       break;
02408    default:
02409       break;
02410    }
02411 
02412    return res;
02413 }

static void __ast_change_name_nolink ( struct ast_channel chan,
const char *  newname 
) [static]

this function simply changes the name of the channel and issues a manager_event with out unlinking and linking the channel from the ao2_container. This should only be used when the channel has already been unlinked from the ao2_container.

Definition at line 4835 of file channel.c.

References ast_string_field_set, EVENT_FLAG_CALL, manager_event, name, ast_channel::name, and ast_channel::uniqueid.

Referenced by ast_change_name(), and ast_do_masquerade().

04836 {
04837    manager_event(EVENT_FLAG_CALL, "Rename", "Channel: %s\r\nNewname: %s\r\nUniqueid: %s\r\n", chan->name, newname, chan->uniqueid);
04838    ast_string_field_set(chan, name, newname);
04839 }

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 char *  linkedid,
const int  amaflag,
const char *  file,
int  line,
const char *  function,
const char *  name_fmt,
  ... 
) [read]

Create a channel structure.

Since:
1.6.3
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 1002 of file channel.c.

References __ast_channel_alloc_ap().

01008 {
01009    va_list ap1, ap2;
01010    struct ast_channel *result;
01011 
01012    va_start(ap1, name_fmt);
01013    va_start(ap2, name_fmt);
01014    result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
01015                linkedid, amaflag, file, line, function, name_fmt, ap1, ap2);
01016    va_end(ap1);
01017    va_end(ap2);
01018 
01019    return result;
01020 }

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 char *  linkedid,
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 786 of file channel.c.

References __ao2_alloc_debug(), ast_channel::_state, ast_channel::accountcode, accountcode, ast_channel::alertpipe, ast_channel::amaflags, ao2_alloc, ao2_link, AST_ALERT_FD, ast_atomic_fetchadd_int(), ast_cdr_alloc(), ast_cdr_init(), ast_cdr_start(), AST_CEL_CHANNEL_START, ast_cel_report_event(), ast_channel_destructor(), ast_channel_set_fd(), ast_channel_unref, ast_config_AST_SYSTEM_NAME, ast_copy_string(), ast_default_accountcode, ast_default_amaflags, ast_free, AST_LIST_HEAD_INIT_NOLOCK, ast_log(), AST_MAX_FDS, 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::autochans, ast_channel::cdr, channels, ast_channel::cid, ast_callerid::cid_name, ast_callerid::cid_num, ast_channel::context, ast_channel::datastores, defaultlanguage, errno, EVENT_FLAG_CALL, ast_channel::exten, ast_channel::fds, ast_channel::fin, chanlist::flags, ast_channel::fout, language, LOG_WARNING, manager_event, ast_channel::name, 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, ast_channel::uniqueid, and ast_channel::varshead.

Referenced by __ast_channel_alloc(), and ast_channel_alloc().

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

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

Definition at line 1058 of file channel.c.

References ast_channel::alertpipe, ast_channel_lock, ast_channel_unlock, AST_CONTROL_HANGUP, AST_FLAG_BLOCKING, AST_FRAME_CONTROL, AST_FRAME_VOICE, ast_frdup(), ast_frfree, AST_LIST_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_HEAD, AST_LIST_TRAVERSE, ast_log(), ast_test_flag, ast_timer_enable_continuous(), ast_channel::blocker, errno, f, ast_frame::frame_list, frames, ast_frame::frametype, LOG_WARNING, ast_channel::name, ast_channel::readq, ast_frame::subclass, ast_channel::timer, and ast_channel::timingfd.

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

01059 {
01060    struct ast_frame *f;
01061    struct ast_frame *cur;
01062    int blah = 1;
01063    unsigned int new_frames = 0;
01064    unsigned int new_voice_frames = 0;
01065    unsigned int queued_frames = 0;
01066    unsigned int queued_voice_frames = 0;
01067    AST_LIST_HEAD_NOLOCK(, ast_frame) frames;
01068 
01069    ast_channel_lock(chan);
01070 
01071    /* See if the last frame on the queue is a hangup, if so don't queue anything */
01072    if ((cur = AST_LIST_LAST(&chan->readq)) &&
01073        (cur->frametype == AST_FRAME_CONTROL) &&
01074        (cur->subclass == AST_CONTROL_HANGUP)) {
01075       ast_channel_unlock(chan);
01076       return 0;
01077    }
01078 
01079    /* Build copies of all the frames and count them */
01080    AST_LIST_HEAD_INIT_NOLOCK(&frames);
01081    for (cur = fin; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
01082       if (!(f = ast_frdup(cur))) {
01083          ast_frfree(AST_LIST_FIRST(&frames));
01084          return -1;
01085       }
01086 
01087       AST_LIST_INSERT_TAIL(&frames, f, frame_list);
01088       new_frames++;
01089       if (f->frametype == AST_FRAME_VOICE) {
01090          new_voice_frames++;
01091       }
01092    }
01093 
01094    /* Count how many frames exist on the queue */
01095    AST_LIST_TRAVERSE(&chan->readq, cur, frame_list) {
01096       queued_frames++;
01097       if (cur->frametype == AST_FRAME_VOICE) {
01098          queued_voice_frames++;
01099       }
01100    }
01101 
01102    if ((queued_frames + new_frames) > 128) {
01103       ast_log(LOG_WARNING, "Exceptionally long queue length queuing to %s\n", chan->name);
01104       while ((f = AST_LIST_REMOVE_HEAD(&frames, frame_list))) {
01105          ast_frfree(f);
01106       }
01107       ast_channel_unlock(chan);
01108       return 0;
01109    }
01110 
01111    if ((queued_voice_frames + new_voice_frames) > 96) {
01112       ast_log(LOG_WARNING, "Exceptionally long voice queue length queuing to %s\n", chan->name);
01113       while ((f = AST_LIST_REMOVE_HEAD(&frames, frame_list))) {
01114          ast_frfree(f);
01115       }
01116       ast_channel_unlock(chan);
01117       return 0;
01118    }
01119 
01120    if (after) {
01121       AST_LIST_INSERT_LIST_AFTER(&chan->readq, &frames, after, frame_list);
01122    } else {
01123       if (head) {
01124          AST_LIST_APPEND_LIST(&frames, &chan->readq, frame_list);
01125          AST_LIST_HEAD_INIT_NOLOCK(&chan->readq);
01126       }
01127       AST_LIST_APPEND_LIST(&chan->readq, &frames, frame_list);
01128    }
01129 
01130    if (chan->alertpipe[1] > -1) {
01131       if (write(chan->alertpipe[1], &blah, new_frames * sizeof(blah)) != (new_frames * sizeof(blah))) {
01132          ast_log(LOG_WARNING, "Unable to write to alert pipe on %s (qlen = %d): %s!\n",
01133             chan->name, queued_frames, strerror(errno));
01134       }
01135    } else if (chan->timingfd > -1) {
01136       ast_timer_enable_continuous(chan->timer);
01137    } else if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
01138       pthread_kill(chan->blocker, SIGURG);
01139    }
01140 
01141    ast_channel_unlock(chan);
01142 
01143    return 0;
01144 }

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 3079 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_CEL_ANSWER, ast_cel_report_event(), ast_channel_lock, 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_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, cause, 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_frame::frame_list, 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::name, ast_channel::nativeformats, ast_channel::outsmpl, queue_dtmf_readq(), ast_channel_tech::read, ast_channel_monitor::read_stream, ast_channel::readq, 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().

03080 {
03081    struct ast_frame *f = NULL;   /* the return value */
03082    int blah;
03083    int prestate;
03084    int cause = 0;
03085 
03086    /* this function is very long so make sure there is only one return
03087     * point at the end (there are only two exceptions to this).
03088     */
03089 
03090    if (chan->masq) {
03091       if (ast_do_masquerade(chan))
03092          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
03093       else
03094          f =  &ast_null_frame;
03095       return f;
03096    }
03097 
03098    /* if here, no masq has happened, lock the channel and proceed */
03099    ast_channel_lock(chan);
03100 
03101    /* Stop if we're a zombie or need a soft hangup */
03102    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
03103       if (chan->generator)
03104          ast_deactivate_generator(chan);
03105       goto done;
03106    }
03107 
03108 #ifdef AST_DEVMODE
03109    /* 
03110     * The ast_waitfor() code records which of the channel's file descriptors reported that
03111     * data is available.  In theory, ast_read() should only be called after ast_waitfor()
03112     * reports that a channel has data available for reading.  However, there still may be
03113     * some edge cases throughout the code where ast_read() is called improperly.  This can
03114     * potentially cause problems, so if this is a developer build, make a lot of noise if
03115     * this happens so that it can be addressed. 
03116     */
03117    if (chan->fdno == -1) {
03118       ast_log(LOG_ERROR, "ast_read() called with no recorded file descriptor.\n");
03119    }
03120 #endif
03121 
03122    prestate = chan->_state;
03123 
03124    /* Read and ignore anything on the alertpipe, but read only
03125       one sizeof(blah) per frame that we send from it */
03126    if (chan->alertpipe[0] > -1) {
03127       int flags = fcntl(chan->alertpipe[0], F_GETFL);
03128       /* For some odd reason, the alertpipe occasionally loses nonblocking status,
03129        * which immediately causes a deadlock scenario.  Detect and prevent this. */
03130       if ((flags & O_NONBLOCK) == 0) {
03131          ast_log(LOG_ERROR, "Alertpipe on channel %s lost O_NONBLOCK?!!\n", chan->name);
03132          if (fcntl(chan->alertpipe[0], F_SETFL, flags | O_NONBLOCK) < 0) {
03133             ast_log(LOG_WARNING, "Unable to set alertpipe nonblocking! (%d: %s)\n", errno, strerror(errno));
03134             f = &ast_null_frame;
03135             goto done;
03136          }
03137       }
03138       if (read(chan->alertpipe[0], &blah, sizeof(blah)) < 0) {
03139          if (errno != EINTR && errno != EAGAIN)
03140             ast_log(LOG_WARNING, "read() failed: %s\n", strerror(errno));
03141       }
03142    }
03143 
03144    if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD) {
03145       enum ast_timer_event res;
03146 
03147       ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03148 
03149       res = ast_timer_get_event(chan->timer);
03150 
03151       switch (res) {
03152       case AST_TIMING_EVENT_EXPIRED:
03153          ast_timer_ack(chan->timer, 1);
03154 
03155          if (chan->timingfunc) {
03156             /* save a copy of func/data before unlocking the channel */
03157             int (*func)(const void *) = chan->timingfunc;
03158             void *data = chan->timingdata;
03159             chan->fdno = -1;
03160             ast_channel_unlock(chan);
03161             func(data);
03162          } else {
03163             ast_timer_set_rate(chan->timer, 0);
03164             chan->fdno = -1;
03165             ast_channel_unlock(chan);
03166          }
03167 
03168          /* cannot 'goto done' because the channel is already unlocked */
03169          return &ast_null_frame;
03170 
03171       case AST_TIMING_EVENT_CONTINUOUS:
03172          if (AST_LIST_EMPTY(&chan->readq) || 
03173             !AST_LIST_NEXT(AST_LIST_FIRST(&chan->readq), frame_list)) {
03174             ast_timer_disable_continuous(chan->timer);
03175          }
03176          break;
03177       }
03178 
03179    } else if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
03180       /* if the AST_GENERATOR_FD is set, call the generator with args
03181        * set to -1 so it can do whatever it needs to.
03182        */
03183       void *tmp = chan->generatordata;
03184       chan->generatordata = NULL;     /* reset to let ast_write get through */
03185       chan->generator->generate(chan, tmp, -1, -1);
03186       chan->generatordata = tmp;
03187       f = &ast_null_frame;
03188       chan->fdno = -1;
03189       goto done;
03190    }
03191 
03192    /* Check for pending read queue */
03193    if (!AST_LIST_EMPTY(&chan->readq)) {
03194       int skip_dtmf = should_skip_dtmf(chan);
03195 
03196       AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->readq, f, frame_list) {
03197          /* We have to be picky about which frame we pull off of the readq because
03198           * there are cases where we want to leave DTMF frames on the queue until
03199           * some later time. */
03200 
03201          if ( (f->frametype == AST_FRAME_DTMF_BEGIN || f->frametype == AST_FRAME_DTMF_END) && skip_dtmf) {
03202             continue;
03203          }
03204 
03205          AST_LIST_REMOVE_CURRENT(frame_list);
03206          break;
03207       }
03208       AST_LIST_TRAVERSE_SAFE_END;
03209       
03210       if (!f) {
03211          /* There were no acceptable frames on the readq. */
03212          f = &ast_null_frame;
03213          if (chan->alertpipe[0] > -1) {
03214             int poke = 0;
03215             /* Restore the state of the alertpipe since we aren't ready for any
03216              * of the frames in the readq. */
03217             if (write(chan->alertpipe[1], &poke, sizeof(poke)) != sizeof(poke)) {
03218                ast_log(LOG_ERROR, "Failed to write to alertpipe: %s\n", strerror(errno));
03219             }
03220          }
03221       }
03222 
03223       /* Interpret hangup and return NULL */
03224       /* XXX why not the same for frames from the channel ? */
03225       if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
03226          cause = f->data.uint32;
03227          ast_frfree(f);
03228          f = NULL;
03229       }
03230    } else {
03231       chan->blocker = pthread_self();
03232       if (ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
03233          if (chan->tech->exception)
03234             f = chan->tech->exception(chan);
03235          else {
03236             ast_log(LOG_WARNING, "Exception flag set on '%s', but no exception handler\n", chan->name);
03237             f = &ast_null_frame;
03238          }
03239          /* Clear the exception flag */
03240          ast_clear_flag(chan, AST_FLAG_EXCEPTION);
03241       } else if (chan->tech->read)
03242          f = chan->tech->read(chan);
03243       else
03244          ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
03245    }
03246 
03247    /*
03248     * Reset the recorded file descriptor that triggered this read so that we can
03249     * easily detect when ast_read() is called without properly using ast_waitfor().
03250     */
03251    chan->fdno = -1;
03252 
03253    if (f) {
03254       struct ast_frame *readq_tail = AST_LIST_LAST(&chan->readq);
03255 
03256       /* if the channel driver returned more than one frame, stuff the excess
03257          into the readq for the next ast_read call
03258       */
03259       if (AST_LIST_NEXT(f, frame_list)) {
03260          ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list));
03261          ast_frfree(AST_LIST_NEXT(f, frame_list));
03262          AST_LIST_NEXT(f, frame_list) = NULL;
03263       }
03264 
03265       switch (f->frametype) {
03266       case AST_FRAME_CONTROL:
03267          if (f->subclass == AST_CONTROL_ANSWER) {
03268             if (!ast_test_flag(chan, AST_FLAG_OUTGOING)) {
03269                ast_debug(1, "Ignoring answer on an inbound call!\n");
03270                ast_frfree(f);
03271                f = &ast_null_frame;
03272             } else if (prestate == AST_STATE_UP) {
03273                ast_debug(1, "Dropping duplicate answer!\n");
03274                ast_frfree(f);
03275                f = &ast_null_frame;
03276             } else {
03277                /* Answer the CDR */
03278                ast_setstate(chan, AST_STATE_UP);
03279                /* removed a call to ast_cdr_answer(chan->cdr) from here. */
03280                ast_cel_report_event(chan, AST_CEL_ANSWER, NULL, NULL, NULL);
03281             }
03282          }
03283          break;
03284       case AST_FRAME_DTMF_END:
03285          send_dtmf_event(chan, "Received", f->subclass, "No", "Yes");
03286          ast_log(LOG_DTMF, "DTMF end '%c' received on %s, duration %ld ms\n", f->subclass, chan->name, f->len);
03287          /* Queue it up if DTMF is deferred, or if DTMF emulation is forced. */
03288          if (ast_test_flag(chan, AST_FLAG_DEFER_DTMF) || ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
03289             queue_dtmf_readq(chan, f);
03290             ast_frfree(f);
03291             f = &ast_null_frame;
03292          } else if (!ast_test_flag(chan, AST_FLAG_IN_DTMF | AST_FLAG_END_DTMF_ONLY)) {
03293             if (!ast_tvzero(chan->dtmf_tv) && 
03294                 ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) {
03295                /* If it hasn't been long enough, defer this digit */
03296                queue_dtmf_readq(chan, f);
03297                ast_frfree(f);
03298                f = &ast_null_frame;
03299             } else {
03300                /* There was no begin, turn this into a begin and send the end later */
03301                f->frametype = AST_FRAME_DTMF_BEGIN;
03302                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
03303                chan->emulate_dtmf_digit = f->subclass;
03304                chan->dtmf_tv = ast_tvnow();
03305                if (f->len) {
03306                   if (f->len > AST_MIN_DTMF_DURATION)
03307                      chan->emulate_dtmf_duration = f->len;
03308                   else 
03309                      chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION;
03310                } else
03311                   chan->emulate_dtmf_duration = AST_DEFAULT_EMULATE_DTMF_DURATION;
03312                ast_log(LOG_DTMF, "DTMF begin emulation of '%c' with duration %u queued on %s\n", f->subclass, chan->emulate_dtmf_duration, chan->name);
03313             }
03314             if (chan->audiohooks) {
03315                struct ast_frame *old_frame = f;
03316                /*!
03317                 * \todo XXX It is possible to write a digit to the audiohook twice
03318                 * if the digit was originally read while the channel was in autoservice. */
03319                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03320                if (old_frame != f)
03321                   ast_frfree(old_frame);
03322             }
03323          } else {
03324             struct timeval now = ast_tvnow();
03325             if (ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
03326                ast_log(LOG_DTMF, "DTMF end accepted with begin '%c' on %s\n", f->subclass, chan->name);
03327                ast_clear_flag(chan, AST_FLAG_IN_DTMF);
03328                if (!f->len)
03329                   f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
03330             } else if (!f->len) {
03331                ast_log(LOG_DTMF, "DTMF end accepted without begin '%c' on %s\n", f->subclass, chan->name);
03332                f->len = AST_MIN_DTMF_DURATION;
03333             }
03334             if (f->len < AST_MIN_DTMF_DURATION && !ast_test_flag(chan, AST_FLAG_END_DTMF_ONLY)) {
03335                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);
03336                ast_set_flag(chan, AST_FLAG_EMULATE_DTMF);
03337                chan->emulate_dtmf_digit = f->subclass;
03338                chan->emulate_dtmf_duration = AST_MIN_DTMF_DURATION - f->len;
03339                ast_frfree(f);
03340                f = &ast_null_frame;
03341             } else {
03342                ast_log(LOG_DTMF, "DTMF end passthrough '%c' on %s\n", f->subclass, chan->name);
03343                if (f->len < AST_MIN_DTMF_DURATION) {
03344                   f->len = AST_MIN_DTMF_DURATION;
03345                }
03346                chan->dtmf_tv = now;
03347             }
03348             if (chan->audiohooks) {
03349                struct ast_frame *old_frame = f;
03350                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03351                if (old_frame != f)
03352                   ast_frfree(old_frame);
03353             }
03354          }
03355          break;
03356       case AST_FRAME_DTMF_BEGIN:
03357          send_dtmf_event(chan, "Received", f->subclass, "Yes", "No");
03358          ast_log(LOG_DTMF, "DTMF begin '%c' received on %s\n", f->subclass, chan->name);
03359          if ( ast_test_flag(chan, AST_FLAG_DEFER_DTMF | AST_FLAG_END_DTMF_ONLY | AST_FLAG_EMULATE_DTMF) || 
03360              (!ast_tvzero(chan->dtmf_tv) && 
03361                ast_tvdiff_ms(ast_tvnow(), chan->dtmf_tv) < AST_MIN_DTMF_GAP) ) {
03362             ast_log(LOG_DTMF, "DTMF begin ignored '%c' on %s\n", f->subclass, chan->name);
03363             ast_frfree(f);
03364             f = &ast_null_frame;
03365          } else {
03366             ast_set_flag(chan, AST_FLAG_IN_DTMF);
03367             chan->dtmf_tv = ast_tvnow();
03368             ast_log(LOG_DTMF, "DTMF begin passthrough '%c' on %s\n", f->subclass, chan->name);
03369          }
03370          break;
03371       case AST_FRAME_NULL:
03372          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
03373           * is reached , because we want to make sure we pass at least one
03374           * voice frame through before starting the next digit, to ensure a gap
03375           * between DTMF digits. */
03376          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF)) {
03377             struct timeval now = ast_tvnow();
03378             if (!chan->emulate_dtmf_duration) {
03379                ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
03380                chan->emulate_dtmf_digit = 0;
03381             } else if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
03382                chan->emulate_dtmf_duration = 0;
03383                ast_frfree(f);
03384                f = &chan->dtmff;
03385                f->frametype = AST_FRAME_DTMF_END;
03386                f->subclass = chan->emulate_dtmf_digit;
03387                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
03388                chan->dtmf_tv = now;
03389                ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
03390                chan->emulate_dtmf_digit = 0;
03391                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
03392                if (chan->audiohooks) {
03393                   struct ast_frame *old_frame = f;
03394                   f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03395                   if (old_frame != f) {
03396                      ast_frfree(old_frame);
03397                   }
03398                }
03399             }
03400          }
03401          break;
03402       case AST_FRAME_VOICE:
03403          /* The EMULATE_DTMF flag must be cleared here as opposed to when the duration
03404           * is reached , because we want to make sure we pass at least one
03405           * voice frame through before starting the next digit, to ensure a gap
03406           * between DTMF digits. */
03407          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !chan->emulate_dtmf_duration) {
03408             ast_clear_flag(chan, AST_FLAG_EMULATE_DTMF);
03409             chan->emulate_dtmf_digit = 0;
03410          }
03411 
03412          if (dropaudio || ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
03413             if (dropaudio)
03414                ast_read_generator_actions(chan, f);
03415             ast_frfree(f);
03416             f = &ast_null_frame;
03417          }
03418 
03419          if (ast_test_flag(chan, AST_FLAG_EMULATE_DTMF) && !ast_test_flag(chan, AST_FLAG_IN_DTMF)) {
03420             struct timeval now = ast_tvnow();
03421             if (ast_tvdiff_ms(now, chan->dtmf_tv) >= chan->emulate_dtmf_duration) {
03422                chan->emulate_dtmf_duration = 0;
03423                ast_frfree(f);
03424                f = &chan->dtmff;
03425                f->frametype = AST_FRAME_DTMF_END;
03426                f->subclass = chan->emulate_dtmf_digit;
03427                f->len = ast_tvdiff_ms(now, chan->dtmf_tv);
03428                chan->dtmf_tv = now;
03429                if (chan->audiohooks) {
03430                   struct ast_frame *old_frame = f;
03431                   f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03432                   if (old_frame != f)
03433                      ast_frfree(old_frame);
03434                }
03435                ast_log(LOG_DTMF, "DTMF end emulation of '%c' queued on %s\n", f->subclass, chan->name);
03436             } else {
03437                /* Drop voice frames while we're still in the middle of the digit */
03438                ast_frfree(f);
03439                f = &ast_null_frame;
03440             }
03441          } else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass & chan->nativeformats)) {
03442             /* This frame is not one of the current native formats -- drop it on the floor */
03443             char to[200];
03444             ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
03445                chan->name, ast_getformatname(f->subclass), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats));
03446             ast_frfree(f);
03447             f = &ast_null_frame;
03448          } else if ((f->frametype == AST_FRAME_VOICE)) {
03449             /* Send frame to audiohooks if present */
03450             if (chan->audiohooks) {
03451                struct ast_frame *old_frame = f;
03452                f = ast_audiohook_write_list(chan, chan->audiohooks, AST_AUDIOHOOK_DIRECTION_READ, f);
03453                if (old_frame != f)
03454                   ast_frfree(old_frame);
03455             }
03456             if (chan->monitor && chan->monitor->read_stream ) {
03457                /* XXX what does this do ? */
03458 #ifndef MONITOR_CONSTANT_DELAY
03459                int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
03460                if (jump >= 0) {
03461                   jump = chan->outsmpl - chan->insmpl;
03462                   if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
03463                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
03464                   chan->insmpl += jump + f->samples;
03465                } else
03466                   chan->insmpl+= f->samples;
03467 #else
03468                int jump = chan->outsmpl - chan->insmpl;
03469                if (jump - MONITOR_DELAY >= 0) {
03470                   if (ast_seekstream(chan->monitor->read_stream, jump - f->samples, SEEK_FORCECUR) == -1)
03471                      ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
03472                   chan->insmpl += jump;
03473                } else
03474                   chan->insmpl += f->samples;
03475 #endif
03476                if (chan->monitor->state == AST_MONITOR_RUNNING) {
03477                   if (ast_writestream(chan->monitor->read_stream, f) < 0)
03478                      ast_log(LOG_WARNING, "Failed to write data to channel monitor read stream\n");
03479                }
03480             }
03481 
03482             if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL) {
03483                f = &ast_null_frame;
03484             }
03485 
03486             /* it is possible for the translation process on chan->readtrans to have
03487                produced multiple frames from the single input frame we passed it; if
03488                this happens, queue the additional frames *before* the frames we may
03489                have queued earlier. if the readq was empty, put them at the head of
03490                the queue, and if it was not, put them just after the frame that was
03491                at the end of the queue.
03492             */
03493             if (AST_LIST_NEXT(f, frame_list)) {
03494                if (!readq_tail) {
03495                   ast_queue_frame_head(chan, AST_LIST_NEXT(f, frame_list));
03496                } else {
03497                   __ast_queue_frame(chan, AST_LIST_NEXT(f, frame_list), 0, readq_tail);
03498                }
03499                ast_frfree(AST_LIST_NEXT(f, frame_list));
03500                AST_LIST_NEXT(f, frame_list) = NULL;
03501             }
03502 
03503             /* Run generator sitting on the line if timing device not available
03504             * and synchronous generation of outgoing frames is necessary       */
03505             ast_read_generator_actions(chan, f);
03506          }
03507       default:
03508          /* Just pass it on! */
03509          break;
03510       }
03511    } else {
03512       /* Make sure we always return NULL in the future */
03513       chan->_softhangup |= AST_SOFTHANGUP_DEV;
03514       if (cause)
03515          chan->hangupcause = cause;
03516       if (chan->generator)
03517          ast_deactivate_generator(chan);
03518       /* We no longer End the CDR here */
03519    }
03520 
03521    /* High bit prints debugging */
03522    if (chan->fin & DEBUGCHAN_FLAG)
03523       ast_frame_dump(chan->name, f, "<<");
03524    chan->fin = FRAMECOUNT_INC(chan->fin);
03525 
03526 done:
03527    if (chan->music_state && chan->generator && chan->generator->digit && f && f->frametype == AST_FRAME_DTMF_END)
03528       chan->generator->digit(chan, f->subclass);
03529 
03530    ast_channel_unlock(chan);
03531    return f;
03532 }

struct ast_channel* __ast_request_and_dial ( const char *  type,
int  format,
const struct ast_channel requestor,
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 4342 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_channel_set_connected_line(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HANGUP, AST_CONTROL_HOLD, AST_CONTROL_PROCEEDING, AST_CONTROL_PROGRESS, AST_CONTROL_REDIRECTING, 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_party_connected_line_set_init(), AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED, ast_read(), ast_request(), ast_set_callerid(), ast_set_flag, ast_set_variables(), AST_STATE_UP, ast_strlen_zero(), ast_waitfor(), ast_channel::call_forward, cause, ast_channel::cdr, outgoing_helper::cid_name, outgoing_helper::cid_num, ast_channel::connected, ast_channel::context, outgoing_helper::context, ast_channel::exten, outgoing_helper::exten, f, ast_frame::frametype, handle_cause(), ast_channel::hangupcause, ast_party_connected_line::id, LOG_NOTICE, ast_party_id::name, ast_party_id::number, ast_party_id::number_presentation, 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().

04343 {
04344    int dummy_outstate;
04345    int cause = 0;
04346    struct ast_channel *chan;
04347    int res = 0;
04348    int last_subclass = 0;
04349    struct ast_party_connected_line connected;
04350    
04351    if (outstate)
04352       *outstate = 0;
04353    else
04354       outstate = &dummy_outstate;   /* make outstate always a valid pointer */
04355 
04356    chan = ast_request(type, format, requestor, data, &cause);
04357    if (!chan) {
04358       ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
04359       handle_cause(cause, outstate);
04360       return NULL;
04361    }
04362 
04363    if (oh) {
04364       if (oh->vars)  
04365          ast_set_variables(chan, oh->vars);
04366       /* XXX why is this necessary, for the parent_channel perhaps ? */
04367       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
04368          ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
04369       if (oh->parent_channel) {
04370          ast_channel_inherit_variables(oh->parent_channel, chan);
04371          ast_channel_datastore_inherit(oh->parent_channel, chan);
04372       }
04373       if (oh->account)
04374          ast_cdr_setaccount(chan, oh->account); 
04375    }
04376 
04377    ast_set_callerid(chan, cid_num, cid_name, cid_num);
04378    ast_set_flag(chan->cdr, AST_CDR_FLAG_ORIGINATED);
04379    ast_party_connected_line_set_init(&connected, &chan->connected);
04380    connected.id.number = (char *) cid_num;
04381    connected.id.name = (char *) cid_name;
04382    connected.id.number_presentation = AST_PRES_ALLOWED_USER_NUMBER_NOT_SCREENED;
04383    ast_channel_set_connected_line(chan, &connected);
04384 
04385    if (ast_call(chan, data, 0)) {   /* ast_call failed... */
04386       ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
04387    } else {
04388       res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
04389       while (timeout && chan->_state != AST_STATE_UP) {
04390          struct ast_frame *f;
04391          res = ast_waitfor(chan, timeout);
04392          if (res == 0) { /* timeout, treat it like ringing */
04393             *outstate = AST_CONTROL_RINGING;
04394             break;
04395          }
04396          if (res < 0) /* error or done */
04397             break;
04398          if (timeout > -1)
04399             timeout = res;
04400          if (!ast_strlen_zero(chan->call_forward)) {
04401             if (!(chan = ast_call_forward(NULL, chan, &timeout, format, oh, outstate))) {
04402                return NULL;
04403             }
04404             continue;
04405          }
04406 
04407          f = ast_read(chan);
04408          if (!f) {
04409             *outstate = AST_CONTROL_HANGUP;
04410             res = 0;
04411             break;
04412          }
04413          if (f->frametype == AST_FRAME_CONTROL) {
04414             switch (f->subclass) {
04415             case AST_CONTROL_RINGING:  /* record but keep going */
04416                *outstate = f->subclass;
04417                break;
04418 
04419             case AST_CONTROL_BUSY:
04420             case AST_CONTROL_CONGESTION:
04421             case AST_CONTROL_ANSWER:
04422                *outstate = f->subclass;
04423                timeout = 0;      /* trick to force exit from the while() */
04424                break;
04425 
04426             /* Ignore these */
04427             case AST_CONTROL_PROGRESS:
04428             case AST_CONTROL_PROCEEDING:
04429             case AST_CONTROL_HOLD:
04430             case AST_CONTROL_UNHOLD:
04431             case AST_CONTROL_VIDUPDATE:
04432             case AST_CONTROL_SRCUPDATE:
04433             case AST_CONTROL_CONNECTED_LINE:
04434             case AST_CONTROL_REDIRECTING:
04435             case -1:       /* Ignore -- just stopping indications */
04436                break;
04437 
04438             default:
04439                ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
04440             }
04441             last_subclass = f->subclass;
04442          }
04443          ast_frfree(f);
04444       }
04445    }
04446 
04447    /* Final fixups */
04448    if (oh) {
04449       if (!ast_strlen_zero(oh->context))
04450          ast_copy_string(chan->context, oh->context, sizeof(chan->context));
04451       if (!ast_strlen_zero(oh->exten))
04452          ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
04453       if (oh->priority) 
04454          chan->priority = oh->priority;
04455    }
04456    if (chan->_state == AST_STATE_UP)
04457       *outstate = AST_CONTROL_ANSWER;
04458 
04459    if (res <= 0) {
04460       if ( AST_CONTROL_RINGING == last_subclass ) 
04461          chan->hangupcause = AST_CAUSE_NO_ANSWER;
04462       if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
04463          ast_cdr_init(chan->cdr, chan);
04464       if (chan->cdr) {
04465          char tmp[256];
04466          snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
04467          ast_cdr_setapp(chan->cdr,"Dial",tmp);
04468          ast_cdr_update(chan);
04469          ast_cdr_start(chan->cdr);
04470          ast_cdr_end(chan->cdr);
04471          /* If the cause wasn't handled properly */
04472          if (ast_cdr_disposition(chan->cdr,chan->hangupcause))
04473             ast_cdr_failed(chan->cdr);
04474       }
04475       ast_hangup(chan);
04476       chan = NULL;
04477    }
04478    return chan;
04479 }

static void __fini_backends ( void   )  [static]

Definition at line 127 of file channel.c.

00142 {

static void __init_backends ( void   )  [static]

Definition at line 127 of file channel.c.

00142 {

static void __init_state2str_threadbuf ( void   )  [static]

Definition at line 90 of file channel.c.

00105 {

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

Activate a given generator

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

02466 {
02467    int res = 0;
02468 
02469    ast_channel_lock(chan);
02470 
02471    if (chan->generatordata) {
02472       if (chan->generator && chan->generator->release)
02473          chan->generator->release(chan, chan->generatordata);
02474       chan->generatordata = NULL;
02475    }
02476 
02477    ast_prod(chan);
02478    if (gen->alloc && !(chan->generatordata = gen->alloc(chan, params))) {
02479       res = -1;
02480    }
02481    
02482    if (!res) {
02483       ast_settimeout(chan, 50, generator_force, chan);
02484       chan->generator = gen;
02485    }
02486 
02487    ast_channel_unlock(chan);
02488 
02489    return res;
02490 }

int ast_active_channels ( void   ) 

returns number of active/allocated channels

Returns:
number of active/allocated channels

Definition at line 513 of file channel.c.

References ao2_container_count(), and channels.

Referenced by action_corestatus(), ast_var_channels(), ast_var_channels_table(), dahdi_restart(), handle_chanlist(), handle_show_settings(), and quit_handler().

00514 {
00515    return channels ? ao2_container_count(channels) : 0;
00516 }

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

02416 {
02417    return __ast_answer(chan, 0, 1);
02418 }

void ast_begin_shutdown ( int  hangup  ) 

Initiate system shutdown -- prevents new channels from being allocated.

Parameters:
hangup If "hangup" is non-zero, all existing channels will receive soft hangups

Definition at line 503 of file channel.c.

References ao2_callback, ast_channel_softhangup_cb(), channels, OBJ_MULTIPLE, and OBJ_NODATA.

Referenced by quit_handler().

00504 {
00505    shutting_down = 1;
00506 
00507    if (hangup) {
00508       ao2_callback(channels, OBJ_NODATA | OBJ_MULTIPLE, ast_channel_softhangup_cb, NULL);
00509    }
00510 }

int ast_best_codec ( int  fmts  ) 

Pick the best audio codec.

Pick the best codec Choose the best codec... Uhhh... Yah.

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 722 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_SIREN14, AST_FORMAT_SIREN7, 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(), bridge_make_compatible(), builtin_atxfer(), echo_exec(), findmeexec(), gtalk_new(), handle_open_receive_channel_ack_message(), iax2_request(), jingle_new(), local_new(), login_exec(), mgcp_new(), multicast_rtp_request(), set_format(), sip_new(), skinny_new(), skinny_set_rtp_peer(), socket_process(), start_rtp(), transmit_connect(), and unistim_new().

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

struct ast_channel* ast_bridged_channel ( struct ast_channel chan  )  [read]

Find bridged channel.

Note:
This function does _not_ return a reference to the bridged channel. The reason for this is mostly historical. It _should_ return a reference, but it will take a lot of work to make the code base account for that. So, for now, the old rules still apply for how to handle this function. If this function is being used from the channel thread that owns the channel, then a reference is already held, and channel locking is not required to guarantee that the channel will stay around. If this function is used outside of the associated channel thread, the channel parameter 'chan' MUST be locked before calling this function. Also, 'chan' must remain locked for the entire time that the result of this function is being used.
Parameters:
chan Current channel
Returns:
A pointer to the bridged channel

Definition at line 5504 of file channel.c.

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

Referenced by __analog_handle_event(), __analog_ss_thread(), __dahdi_exception(), _skinny_show_lines(), action_agents(), action_coreshowchannels(), agents_show(), agents_show_online(), analog_attempt_transfer(), analog_exception(), analog_hangup(), analog_ss_thread(), ast_bridge_call(), ast_cel_report_event(), ast_channel_masquerade(), ast_channel_set_linkgroup(), ast_rtp_instance_set_stats_vars(), ast_set_hangupsource(), ast_var_channel_bridge(), ast_var_channels_table(), attempt_transfer(), cb_events(), channel_spy(), check_bridge(), common_exec(), console_transfer(), create_jb(), dahdi_handle_event(), dahdi_hangup(), export_aoc_vars(), func_channel_read(), get_refer_info(), handle_chanlist(), handle_hd_hf(), handle_invite_replaces(), handle_request(), handle_request_bye(), handle_request_info(), handle_request_refer(), handle_showchan(), handle_soft_key_event_message(), handle_stimulus_message(), key_call(), key_dial_page(), local_attended_transfer(), mgcp_hangup(), mgcp_ss(), misdn_attempt_transfer(), mixmonitor_thread(), my_get_sigpvt_bridged_channel(), park_call_full(), schedule_delivery(), sip_hangup(), sip_read(), sip_set_rtp_peer(), skinny_transfer(), socket_process(), start_spying(), startmon(), TransferCallStep1(), and unistim_hangup().

05505 {
05506    struct ast_channel *bridged;
05507    bridged = chan->_bridge;
05508    if (bridged && bridged->tech->bridged_channel)
05509       bridged = bridged->tech->bridged_channel(chan, bridged);
05510    return bridged;
05511 }

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

References AST_CDR_FLAG_DIALED, 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(), ast_call_forward(), attempt_reconnect(), begin_dial_channel(), connect_link(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), play_sound_file(), ring_entry(), rpt(), rpt_exec(), and wait_for_answer().

04543 {
04544    /* Place an outgoing call, but don't wait any longer than timeout ms before returning.
04545       If the remote end does not answer within the timeout, then do NOT hang up, but
04546       return anyway.  */
04547    int res = -1;
04548    /* Stop if we're a zombie or need a soft hangup */
04549    ast_channel_lock(chan);
04550    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE) && !ast_check_hangup(chan)) {
04551       if (chan->cdr)
04552          ast_set_flag(chan->cdr, AST_CDR_FLAG_DIALED);
04553       if (chan->tech->call)
04554          res = chan->tech->call(chan, addr, timeout);
04555       ast_set_flag(chan, AST_FLAG_OUTGOING);
04556    }
04557    ast_channel_unlock(chan);
04558    return res;
04559 }

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

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

Referenced by __ast_request_and_dial(), and feature_request_and_dial().

04267 {
04268    char tmpchan[256];
04269    struct ast_channel *new = NULL;
04270    struct ast_party_redirecting *apr = &orig->redirecting;
04271    char *data, *type;
04272    int cause = 0;
04273 
04274    /* gather data and request the new forward channel */
04275    ast_copy_string(tmpchan, orig->call_forward, sizeof(tmpchan));
04276    if ((data = strchr(tmpchan, '/'))) {
04277       *data++ = '\0';
04278       type = tmpchan;
04279    } else {
04280       const char *forward_context;
04281       ast_channel_lock(orig);
04282       forward_context = pbx_builtin_getvar_helper(orig, "FORWARD_CONTEXT");
04283       snprintf(tmpchan, sizeof(tmpchan), "%s@%s", orig->call_forward, S_OR(forward_context, orig->context));
04284       ast_channel_unlock(orig);
04285       data = tmpchan;
04286       type = "Local";
04287    }
04288    if (!(new = ast_request(type, format, orig, data, &cause))) {
04289       ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
04290       handle_cause(cause, outstate);
04291       ast_hangup(orig);
04292       return NULL;
04293    }
04294 
04295    ast_channel_set_redirecting(new, apr);
04296 
04297    /* Copy/inherit important information into new channel */
04298    if (oh) {
04299       if (oh->vars) {
04300          ast_set_variables(new, oh->vars);
04301       }
04302       if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name)) {
04303          ast_set_callerid(new, oh->cid_num, oh->cid_name, oh->cid_num);
04304       }
04305       if (oh->parent_channel) {
04306          ast_channel_update_redirecting(oh->parent_channel, apr);
04307          ast_channel_inherit_variables(oh->parent_channel, new);
04308          ast_channel_datastore_inherit(oh->parent_channel, new);
04309       }
04310       if (oh->account) {
04311          ast_cdr_setaccount(new, oh->account);
04312       }
04313    } else if (caller) { /* no outgoing helper so use caller if avaliable */
04314       ast_channel_update_redirecting(caller, apr);
04315       ast_channel_inherit_variables(caller, new);
04316       ast_channel_datastore_inherit(caller, new);
04317    }
04318 
04319    ast_channel_lock(orig);
04320    while (ast_channel_trylock(new)) {
04321       CHANNEL_DEADLOCK_AVOIDANCE(orig);
04322    }
04323    ast_copy_flags(new->cdr, orig->cdr, AST_CDR_FLAG_ORIGINATED);
04324    ast_string_field_set(new, accountcode, orig->accountcode);
04325    ast_party_caller_copy(&new->cid, &orig->cid);
04326    ast_party_connected_line_copy(&new->connected, &orig->connected);
04327    ast_channel_unlock(new);
04328    ast_channel_unlock(orig);
04329 
04330    /* call new channel */
04331    if ((*timeout = ast_call(new, data, 0))) {
04332       ast_log(LOG_NOTICE, "Unable to call forward to channel %s/%s\n", type, (char *)data);
04333       ast_hangup(orig);
04334       ast_hangup(new);
04335       return NULL;
04336    }
04337    ast_hangup(orig);
04338 
04339    return new;
04340 }

void ast_cancel_shutdown ( void   ) 

Cancel a shutdown in progress.

Cancels an existing shutdown and returns to normal operation

Definition at line 519 of file channel.c.

Referenced by handle_abort_shutdown().

00520 {
00521    shutting_down = 0;
00522 }

const char* ast_cause2str ( int  cause  ) 

Gives the string form of a given hangup cause.

Gives the string form of a given cause code.

Definition at line 640 of file channel.c.

References ARRAY_LEN, and causes.

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

00641 {
00642    int x;
00643 
00644    for (x = 0; x < ARRAY_LEN(causes); x++) {
00645       if (causes[x].cause == cause)
00646          return causes[x].desc;
00647    }
00648 
00649    return "Unknown";
00650 }

void ast_change_name ( struct ast_channel chan,
const char *  newname 
)

Change channel name.

Precondition:
Absolutely all channels _MUST_ be unlocked before calling this function.
Parameters:
chan the channel to change the name of
newname the name to change to
Returns:
nothing
Note:
this function must _NEVER_ be used when any channels are locked regardless if it is the channel who's name is being changed or not because it invalidates our channel container locking order... lock container first, then the individual channels, never the other way around.

Definition at line 4841 of file channel.c.

References __ast_change_name_nolink(), ao2_link, ao2_unlink, ast_channel_lock, ast_channel_unlock, and channels.

Referenced by update_name().

04842 {
04843    /* We must re-link, as the hash value will change here. */
04844    ao2_unlink(channels, chan);
04845    ast_channel_lock(chan);
04846    __ast_change_name_nolink(chan, newname);
04847    ast_channel_unlock(chan);
04848    ao2_link(channels, chan);
04849 }

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 char *  linkedid,
const int  amaflag,
const char *  name_fmt,
  ... 
) [read]

Definition at line 7420 of file channel.c.

References __ast_channel_alloc_ap().

07425 {
07426    va_list ap1, ap2;
07427    struct ast_channel *result;
07428 
07429 
07430    va_start(ap1, name_fmt);
07431    va_start(ap2, name_fmt);
07432    result = __ast_channel_alloc_ap(needqueue, state, cid_num, cid_name, acctcode, exten, context,
07433                linkedid, amaflag, __FILE__, __LINE__, __FUNCTION__, name_fmt, ap1, ap2);
07434    va_end(ap1);
07435    va_end(ap2);
07436 
07437    return result;
07438 }

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.

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 5836 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_set_owners_and_peers(), 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_start_time, ast_bridge_config::feature_timer, ast_bridge_config::features_callee, ast_bridge_config::features_caller, 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::name, ast_channel::nativeformats, ast_bridge_config::nexteventts, ast_bridge_config::play_warning, ast_channel::readformat, S_OR, ast_channel_tech::send_digit_begin, ast_bridge_config::start_sound, ast_bridge_config::start_time, ast_channel::tech, ast_bridge_config::timelimit, ast_channel::uniqueid, update_bridge_vars(), ast_bridge_config::warning_freq, ast_bridge_config::warning_sound, and ast_channel::writeformat.

Referenced by ast_bridge_call().

05838 {
05839    struct ast_channel *who = NULL;
05840    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
05841    int nativefailed=0;
05842    int o0nativeformats;
05843    int o1nativeformats;
05844    long time_left_ms=0;
05845    char caller_warning = 0;
05846    char callee_warning = 0;
05847 
05848    if (c0->_bridge) {
05849       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
05850          c0->name, c0->_bridge->name);
05851       return -1;
05852    }
05853    if (c1->_bridge) {
05854       ast_log(LOG_WARNING, "%s is already in a bridge with %s\n",
05855          c1->name, c1->_bridge->name);
05856       return -1;
05857    }
05858    
05859    /* Stop if we're a zombie or need a soft hangup */
05860    if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
05861        ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
05862       return -1;
05863 
05864    *fo = NULL;
05865 
05866    if (ast_tvzero(config->start_time)) {
05867       config->start_time = ast_tvnow();
05868       if (config->start_sound) {
05869          if (caller_warning) {
05870             bridge_playfile(c0, c1, config->start_sound, config->timelimit / 1000);
05871          }
05872          if (callee_warning) {
05873             bridge_playfile(c1, c0, config->start_sound, config->timelimit / 1000);
05874          }
05875       }
05876    }
05877 
05878    /* Keep track of bridge */
05879    c0->_bridge = c1;
05880    c1->_bridge = c0;
05881 
05882    ast_set_owners_and_peers(c0, c1);
05883 
05884    o0nativeformats = c0->nativeformats;
05885    o1nativeformats = c1->nativeformats;
05886 
05887    if (config->feature_timer && !ast_tvzero(config->nexteventts)) {
05888       config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000));
05889    } else if (config->timelimit) {
05890       time_left_ms = config->timelimit - ast_tvdiff_ms(ast_tvnow(), config->start_time);
05891       caller_warning = ast_test_flag(&config->features_caller, AST_FEATURE_PLAY_WARNING);
05892       callee_warning = ast_test_flag(&config->features_callee, AST_FEATURE_PLAY_WARNING);
05893       config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
05894       if ((caller_warning || callee_warning) && config->play_warning) {
05895          long next_warn = config->play_warning;
05896          if (time_left_ms < config->play_warning) {
05897             /* At least one warning was played, which means we are returning after feature */
05898             long warns_passed = (config->play_warning - time_left_ms) / config->warning_freq;
05899             /* It is 'warns_passed * warning_freq' NOT '(warns_passed + 1) * warning_freq',
05900                because nexteventts will be updated once again in the 'if (!to)' block */
05901             next_warn = config->play_warning - warns_passed * config->warning_freq;
05902          }
05903          config->nexteventts = ast_tvsub(config->nexteventts, ast_samp2tv(next_warn, 1000));
05904       }
05905    } else {
05906       config->nexteventts.tv_sec = 0;
05907       config->nexteventts.tv_usec = 0;
05908    }
05909 
05910    if (!c0->tech->send_digit_begin)
05911       ast_set_flag(c1, AST_FLAG_END_DTMF_ONLY);
05912    if (!c1->tech->send_digit_begin)
05913       ast_set_flag(c0, AST_FLAG_END_DTMF_ONLY);
05914    manager_bridge_event(1, 1, c0, c1);
05915 
05916    /* Before we enter in and bridge these two together tell them both the source of audio has changed */
05917    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
05918    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
05919 
05920    for (/* ever */;;) {
05921       struct timeval now = { 0, };
05922       int to;
05923 
05924       to = -1;
05925 
05926       if (!ast_tvzero(config->nexteventts)) {
05927          now = ast_tvnow();
05928          to = ast_tvdiff_ms(config->nexteventts, now);
05929          if (to <= 0) {
05930             if (!config->timelimit) {
05931                res = AST_BRIDGE_COMPLETE;
05932                break;
05933             }
05934             to = 0;
05935          }
05936       }
05937 
05938       if (config->timelimit) {
05939          time_left_ms = config->timelimit - ast_tvdiff_ms(now, config->start_time);
05940          if (time_left_ms < to)
05941             to = time_left_ms;
05942 
05943          if (time_left_ms <= 0) {
05944             if (caller_warning && config->end_sound)
05945                bridge_playfile(c0, c1, config->end_sound, 0);
05946             if (callee_warning && config->end_sound)
05947                bridge_playfile(c1, c0, config->end_sound, 0);
05948             *fo = NULL;
05949             if (who)
05950                *rc = who;
05951             res = 0;
05952             break;
05953          }
05954 
05955          if (!to) {
05956             if (time_left_ms >= 5000 && config->warning_sound && config->play_warning && ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
05957                int t = (time_left_ms + 500) / 1000; /* round to nearest second */
05958                if (caller_warning)
05959                   bridge_playfile(c0, c1, config->warning_sound, t);
05960                if (callee_warning)
05961                   bridge_playfile(c1, c0, config->warning_sound, t);
05962             }
05963 
05964             if (config->warning_freq && (time_left_ms > (config->warning_freq + 5000))) {
05965                config->nexteventts = ast_tvadd(config->nexteventts, ast_samp2tv(config->warning_freq, 1000));
05966             } else {
05967                config->nexteventts = ast_tvadd(config->start_time, ast_samp2tv(config->timelimit, 1000));
05968             }
05969          }
05970          ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
05971       }
05972 
05973       if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
05974          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
05975             c0->_softhangup = 0;
05976          if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
05977             c1->_softhangup = 0;
05978          c0->_bridge = c1;
05979          c1->_bridge = c0;
05980          ast_debug(1, "Unbridge signal received. Ending native bridge.\n");
05981          continue;
05982       }
05983 
05984       /* Stop if we're a zombie or need a soft hangup */
05985       if (ast_test_flag(c0, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c0) ||
05986           ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1)) {
05987          *fo = NULL;
05988          if (who)
05989             *rc = who;
05990          res = 0;
05991          ast_debug(1, "Bridge stops because we're zombie or need a soft hangup: c0=%s, c1=%s, flags: %s,%s,%s,%s\n",
05992             c0->name, c1->name,
05993             ast_test_flag(c0, AST_FLAG_ZOMBIE) ? "Yes" : "No",
05994             ast_check_hangup(c0) ? "Yes" : "No",
05995             ast_test_flag(c1, AST_FLAG_ZOMBIE) ? "Yes" : "No",
05996             ast_check_hangup(c1) ? "Yes" : "No");
05997          break;
05998       }
05999 
06000       update_bridge_vars(c0, c1);
06001 
06002       bridge_play_sounds(c0, c1);
06003 
06004       if (c0->tech->bridge &&
06005           (c0->tech->bridge == c1->tech->bridge) &&
06006           !nativefailed && !c0->monitor && !c1->monitor &&
06007           !c0->audiohooks && !c1->audiohooks && 
06008           !c0->masq && !c0->masqr && !c1->masq && !c1->masqr) {
06009          /* Looks like they share a bridge method and nothing else is in the way */
06010          ast_set_flag(c0, AST_FLAG_NBRIDGE);
06011          ast_set_flag(c1, AST_FLAG_NBRIDGE);
06012          if ((res = c0->tech->bridge(c0, c1, config->flags, fo, rc, to)) == AST_BRIDGE_COMPLETE) {
06013             manager_event(EVENT_FLAG_CALL, "Unlink",
06014                      "Channel1: %s\r\n"
06015                      "Channel2: %s\r\n"
06016                      "Uniqueid1: %s\r\n"
06017                      "Uniqueid2: %s\r\n"
06018                      "CallerID1: %s\r\n"
06019                      "CallerID2: %s\r\n",
06020                      c0->name, c1->name, c0->uniqueid, c1->uniqueid, S_OR(c0->cid.cid_num, "<unknown>"), S_OR(c1->cid.cid_num, "<unknown>"));
06021 
06022             ast_debug(1, "Returning from native bridge, channels: %s, %s\n", c0->name, c1->name);
06023 
06024             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
06025             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
06026 
06027             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
06028                continue;
06029 
06030             c0->_bridge = NULL;
06031             c1->_bridge = NULL;
06032             return res;
06033          } else {
06034             ast_clear_flag(c0, AST_FLAG_NBRIDGE);
06035             ast_clear_flag(c1, AST_FLAG_NBRIDGE);
06036          }
06037          switch (res) {
06038          case AST_BRIDGE_RETRY:
06039             if (config->play_warning) {
06040                ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
06041             }
06042             continue;
06043          default:
06044             ast_verb(3, "Native bridging %s and %s ended\n", c0->name, c1->name);
06045             /* fallthrough */
06046          case AST_BRIDGE_FAILED_NOWARN:
06047             nativefailed++;
06048             break;
06049          }
06050       }
06051 
06052       if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
06053           (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
06054           !(c0->generator || c1->generator)) {
06055          if (ast_channel_make_compatible(c0, c1)) {
06056             ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
06057             manager_bridge_event(0, 1, c0, c1);
06058             return AST_BRIDGE_FAILED;
06059          }
06060          o0nativeformats = c0->nativeformats;
06061          o1nativeformats = c1->nativeformats;
06062       }
06063 
06064       update_bridge_vars(c0, c1);
06065 
06066       res = ast_generic_bridge(c0, c1, config, fo, rc);
06067       if (res != AST_BRIDGE_RETRY) {
06068          break;
06069       } else if (config->feature_timer) {
06070          /* feature timer expired but has not been updated, sending to ast_bridge_call to do so */
06071          break;
06072       }
06073    }
06074 
06075    ast_clear_flag(c0, AST_FLAG_END_DTMF_ONLY);
06076    ast_clear_flag(c1, AST_FLAG_END_DTMF_ONLY);
06077 
06078    /* Now that we have broken the bridge the source will change yet again */
06079    ast_indicate(c0, AST_CONTROL_SRCUPDATE);
06080    ast_indicate(c1, AST_CONTROL_SRCUPDATE);
06081 
06082    c0->_bridge = NULL;
06083    c1->_bridge = NULL;
06084 
06085    manager_event(EVENT_FLAG_CALL, "Unlink",
06086             "Channel1: %s\r\n"
06087             "Channel2: %s\r\n"
06088             "Uniqueid1: %s\r\n"
06089             "Uniqueid2: %s\r\n"
06090             "CallerID1: %s\r\n"
06091             "CallerID2: %s\r\n",
06092             c0->name, c1->name, c0->uniqueid, c1->uniqueid, S_OR(c0->cid.cid_num, "<unknown>"), S_OR(c1->cid.cid_num, "<unknown>"));
06093    ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
06094 
06095    return res;
06096 }

struct ast_channel* ast_channel_callback ( ao2_callback_data_fn cb_fn,
void *  arg,
void *  data,
int  ao2_flags 
) [read]

Call a function with every active channel.

This function executes a callback one time for each active channel on the system. The channel is provided as an argument to the function.

Since:
1.6.3

Definition at line 1230 of file channel.c.

References ao2_callback_data, and channels.

Referenced by ast_cel_check_retire_linkedid(), ast_pickup_call(), handle_core_set_debug_channel(), my_ast_get_channel_by_name_locked(), pickup_by_mark(), and state_notify_build_xml().

01232 {
01233    return ao2_callback_data(channels, ao2_flags, cb_fn, arg, data);
01234 }

static void ast_channel_change_linkedid ( struct ast_channel chan,
const char *  linkedid 
) [static]

Set the channel's linkedid to the given string, and also check to see if the channel's old linkedid is now being retired

Definition at line 4980 of file channel.c.

References ast_cel_check_retire_linkedid(), ast_string_field_set, ast_strlen_zero(), and ast_channel::linkedid.

Referenced by ast_channel_set_linkgroup().

04981 {
04982    /* if the linkedid for this channel is being changed from something, check... */
04983    if (!ast_strlen_zero(chan->linkedid) && 0 != strcmp(chan->linkedid, linkedid)) {
04984       ast_cel_check_retire_linkedid(chan);
04985    }
04986 
04987    ast_string_field_set(chan, linkedid, linkedid);
04988 }

static int ast_channel_cmp_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 1316 of file channel.c.

References ast_channel_lock, ast_channel_unlock, CMP_MATCH, ast_channel::context, ast_channel::exten, ast_channel::macrocontext, ast_channel::macroexten, ast_channel::name, and ast_channel::uniqueid.

01317 {
01318    struct ast_channel *chan = obj, *cmp_args = arg;
01319    size_t name_len;
01320    int ret = CMP_MATCH;
01321 
01322    /* This is sort of a hack.  Basically, we're using an arbitrary field
01323     * in ast_channel to pass the name_len for a prefix match.  If this
01324     * gets changed, then the uses of ao2_find() must be changed, too. */
01325    name_len = cmp_args->rings;
01326 
01327    ast_channel_lock(chan);
01328 
01329    if (cmp_args->name) { /* match by name */
01330       if ((!name_len && strcasecmp(chan->name, cmp_args->name)) ||
01331             (name_len && strncasecmp(chan->name, cmp_args->name, name_len))) {
01332          ret = 0; /* name match failed */
01333       }
01334    } else if (cmp_args->exten) {
01335       if (cmp_args->context && strcasecmp(chan->context, cmp_args->context) &&
01336             strcasecmp(chan->macrocontext, cmp_args->context)) {
01337          ret = 0; /* context match failed */
01338       }
01339       if (ret && strcasecmp(chan->exten, cmp_args->exten) &&
01340             strcasecmp(chan->macroexten, cmp_args->exten)) {
01341          ret = 0; /* exten match failed */
01342       }
01343    } else if (cmp_args->uniqueid) {
01344       if ((!name_len && strcasecmp(chan->uniqueid, cmp_args->uniqueid)) ||
01345             (name_len && strncasecmp(chan->uniqueid, cmp_args->uniqueid, name_len))) {
01346          ret = 0; /* uniqueid match failed */
01347       }
01348    }
01349 
01350    ast_channel_unlock(chan);
01351 
01352    return ret;
01353 }

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

References ast_channel_cmpwhentohangup_tv().

00561 {
00562    struct timeval when = { offset, };
00563    return ast_channel_cmpwhentohangup_tv(chan, when);
00564 }

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

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

Referenced by ast_channel_cmpwhentohangup().

00546 {
00547    struct timeval whentohangup;
00548 
00549    if (ast_tvzero(chan->whentohangup))
00550       return ast_tvzero(offset) ? 0 : -1;
00551 
00552    if (ast_tvzero(offset))
00553       return 1;
00554 
00555    whentohangup = ast_tvadd(offset, ast_tvnow());
00556 
00557    return ast_tvdiff_ms(whentohangup, chan->whentohangup);
00558 }

int ast_channel_connected_line_macro ( struct ast_channel autoservice_chan,
struct ast_channel macro_chan,
const void *  connected_info,
int  caller,
int  frame 
)

Run a connected line interception macro and update a channel's connected line information.

Since:
1.6.3 Whenever we want to update a channel's connected line information, we may need to run a macro so that an administrator can manipulate the information before sending it out. This function both runs the macro and sends the update to the channel.
Parameters:
autoservice_chan Channel to place into autoservice while the macro is running. It is perfectly safe for this to be NULL
macro_chan The channel to run the macro on. Also the channel from which we determine which macro we need to run.
connected_info Either an ast_party_connected_line or ast_frame pointer of type AST_CONTROL_CONNECTED_LINE
caller If true, then run CONNECTED_LINE_CALLER_SEND_MACRO, otherwise run CONNECTED_LINE_CALLEE_SEND_MACRO
frame If true, then connected_info is an ast_frame pointer, otherwise it is an ast_party_connected_line pointer.
Return values:
0 Success
-1 Either the macro does not exist, or there was an error while attempting to run the macro
Todo:
Have multiple return codes based on the MACRO_RESULT
Todo:
Make constants so that caller and frame can be more expressive than just '1' and '0'

Definition at line 7366 of file channel.c.

References ast_app_run_macro(), ast_channel_lock, ast_channel_unlock, ast_channel_update_connected_line(), ast_connected_line_parse_data(), ast_party_connected_line_copy(), ast_strdupa, ast_strlen_zero(), ast_channel::connected, chanlist::connected, pbx_builtin_getvar_helper(), and S_OR.

Referenced by ast_bridge_call(), ast_generic_bridge(), ast_pickup_call(), builtin_atxfer(), builtin_blindtransfer(), feature_request_and_dial(), handle_frame(), pickup_do(), and wait_for_answer().

07367 {
07368    const char *macro;
07369    const char *macro_args;
07370    union {
07371       const struct ast_frame *frame;
07372       const struct ast_party_connected_line *connected;
07373    } pointer;
07374    int retval;
07375 
07376    if (frame) {
07377       pointer.frame = connected_info;
07378    } else {
07379       pointer.connected = connected_info;
07380    }
07381 
07382    ast_channel_lock(macro_chan);
07383    macro = ast_strdupa(S_OR(pbx_builtin_getvar_helper(macro_chan, caller ? "CONNECTED_LINE_CALLER_SEND_MACRO" : "CONNECTED_LINE_CALLEE_SEND_MACRO"), ""));
07384    macro_args = ast_strdupa(S_OR(pbx_builtin_getvar_helper(macro_chan, caller ? "CONNECTED_LINE_CALLER_SEND_MACRO_ARGS" : "CONNECTED_LINE_CALLEE_SEND_MACRO_ARGS"), ""));
07385    ast_channel_unlock(macro_chan);
07386 
07387    if (ast_strlen_zero(macro)) {
07388       return -1;
07389    }
07390 
07391    if (frame) {
07392       ast_connected_line_parse_data(pointer.frame->data.ptr, pointer.frame->datalen, &macro_chan->connected);
07393    } else {
07394       ast_party_connected_line_copy(&macro_chan->connected, pointer.connected);
07395    }
07396 
07397    if (!(retval = ast_app_run_macro(autoservice_chan, macro_chan, macro, macro_args))) {
07398       ast_channel_update_connected_line(macro_chan, &macro_chan->connected);
07399    }
07400 
07401    return retval;
07402 }

int ast_channel_datastore_add ( struct ast_channel chan,
struct ast_datastore datastore 
)

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

References ast_datastore_alloc.

01943 {
01944    return ast_datastore_alloc(info, uid);
01945 }

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

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

Referenced by _macro_exec(), acf_curl_helper(), acf_curlopt_helper(), acf_curlopt_write(), acf_exception_read(), acf_fetch(), acf_iaxvar_read(), acf_iaxvar_write(), acf_odbc_read(), add_agi_cmd(), add_features_datastores(), add_to_agi(), ast_odbc_retrieve_transaction_obj(), attended_transfer_occurred(), audiohook_volume_callback(), audiohook_volume_get(), builtin_atxfer(), calendar_event_read(), calendar_query_exec(), calendar_query_result_exec(), dial_exec_full(), disable_jack_hook(), dundi_result_read(), enable_jack_hook(), enum_result_read(), exec_odbcfinish(), find_speech(), find_transaction(), func_inheritance_write(), func_mute_write(), get_agi_cmd(), get_lock(), gosub_exec(), iax2_call(), jack_hook_callback(), local_read(), local_write(), lock_fixup(), lua_get_state(), manage_parkinglot(), manager_mutestream(), mark_transaction_active(), mute_callback(), park_exec_full(), pbx_builtin_raise_exception(), pop_exec(), queue_transfer_fixup(), release_transaction(), 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().

01984 {
01985    struct ast_datastore *datastore = NULL;
01986    
01987    if (info == NULL)
01988       return NULL;
01989 
01990    AST_LIST_TRAVERSE_SAFE_BEGIN(&chan->datastores, datastore, entry) {
01991       if (datastore->info != info) {
01992          continue;
01993       }
01994 
01995       if (uid == NULL) {
01996          /* matched by type only */
01997          break;
01998       }
01999 
02000       if ((datastore->uid != NULL) && !strcasecmp(uid, datastore->uid)) {
02001          /* Matched by type AND uid */
02002          break;
02003       }
02004    }
02005    AST_LIST_TRAVERSE_SAFE_END;
02006 
02007    return datastore;
02008 }

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

References ast_datastore_free().

01948 {
01949    return ast_datastore_free(datastore);
01950 }

int ast_channel_datastore_inherit ( struct ast_channel from,
struct ast_channel to 
)

Inherit datastores from a parent to a child.

Definition at line 1952 of file channel.c.

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

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

01953 {
01954    struct ast_datastore *datastore = NULL, *datastore2;
01955 
01956    AST_LIST_TRAVERSE(&from->datastores, datastore, entry) {
01957       if (datastore->inheritance > 0) {
01958          datastore2 = ast_datastore_alloc(datastore->info, datastore->uid);
01959          if (datastore2) {
01960             datastore2->data = datastore->info->duplicate ? datastore->info->duplicate(datastore->data) : NULL;
01961             datastore2->inheritance = datastore->inheritance == DATASTORE_INHERIT_FOREVER ? DATASTORE_INHERIT_FOREVER : datastore->inheritance - 1;
01962             AST_LIST_INSERT_TAIL(&to->datastores, datastore2, entry);
01963          }
01964       }
01965    }
01966    return 0;
01967 }

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

References AST_LIST_REMOVE, and ast_channel::datastores.

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

01979 {
01980    return AST_LIST_REMOVE(&chan->datastores, datastore, entry) ? 0 : -1;
01981 }

int ast_channel_defer_dtmf ( struct ast_channel chan  ) 

Set defer DTMF flag on channel.

Defers DTMF so that you only read things like hangups and audio.

Definition at line 1212 of file channel.c.

References AST_FLAG_DEFER_DTMF, ast_set_flag, and ast_test_flag.

Referenced by __adsi_transmit_messages(), and find_cache().

01213 {
01214    int pre = 0;
01215 
01216    if (chan) {
01217       pre = ast_test_flag(chan, AST_FLAG_DEFER_DTMF);
01218       ast_set_flag(chan, AST_FLAG_DEFER_DTMF);
01219    }
01220    return pre;
01221 }

static void ast_channel_destructor ( void *  obj  )  [static]

Free a channel structure.

Definition at line 1811 of file channel.c.

References ast_channel::alertpipe, ast_app_group_discard(), ast_cdr_discard(), AST_CEL_CHANNEL_END, ast_cel_check_retire_linkedid(), ast_cel_report_event(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_unlock, ast_copy_string(), ast_datastore_free(), AST_DEVICE_UNKNOWN, ast_devstate_changed_literal(), ast_free, ast_frfree, ast_jb_destroy(), AST_LIST_REMOVE_HEAD, ast_log(), AST_MAX_FDS, ast_moh_cleanup(), ast_party_connected_line_free(), ast_party_redirecting_free(), ast_string_field_free_memory, ast_timer_close(), ast_tone_zone_unref(), ast_translator_free_path(), ast_var_delete(), ast_channel::cdr, ast_channel::cid, ast_channel::connected, ast_channel::datastores, f, free, free_cid(), LOG_WARNING, ast_channel::monitor, ast_channel::music_state, ast_channel::name, name, ast_channel::pbx, ast_channel::readq, ast_channel::readtrans, ast_channel::redirecting, ast_channel::sched, sched_context_destroy(), ast_channel_monitor::stop, ast_channel::tech_pvt, ast_channel::timer, ast_channel::varshead, ast_channel::writetrans, and ast_channel::zone.

Referenced by __ast_channel_alloc_ap().

01812 {
01813    struct ast_channel *chan = obj;
01814    int fd;
01815 #ifdef HAVE_EPOLL
01816    int i;
01817 #endif
01818    struct ast_var_t *vardata;
01819    struct ast_frame *f;
01820    struct varshead *headp;
01821    struct ast_datastore *datastore = NULL;
01822    char name[AST_CHANNEL_NAME], *dashptr;
01823 
01824    headp = &chan->varshead;
01825 
01826    ast_cel_report_event(chan, AST_CEL_CHANNEL_END, NULL, NULL, NULL);
01827    ast_cel_check_retire_linkedid(chan);
01828 
01829    /* Get rid of each of the data stores on the channel */
01830    while ((datastore = AST_LIST_REMOVE_HEAD(&chan->datastores, entry)))
01831       /* Free the data store */
01832       ast_datastore_free(datastore);
01833 
01834    /* Lock and unlock the channel just to be sure nobody has it locked still
01835       due to a reference that was stored in a datastore. (i.e. app_chanspy) */
01836    ast_channel_lock(chan);
01837    ast_channel_unlock(chan);
01838 
01839    if (chan->tech_pvt) {
01840       ast_log(LOG_WARNING, "Channel '%s' may not have been hung up properly\n", chan->name);
01841       ast_free(chan->tech_pvt);
01842    }
01843 
01844    if (chan->sched)
01845       sched_context_destroy(chan->sched);
01846 
01847    ast_copy_string(name, chan->name, sizeof(name));
01848    if ((dashptr = strrchr(name, '-'))) {
01849       *dashptr = '\0';
01850    }
01851 
01852    /* Stop monitoring */
01853    if (chan->monitor)
01854       chan->monitor->stop( chan, 0 );
01855 
01856    /* If there is native format music-on-hold state, free it */
01857    if (chan->music_state)
01858       ast_moh_cleanup(chan);
01859 
01860    /* Free translators */
01861    if (chan->readtrans)
01862       ast_translator_free_path(chan->readtrans);
01863    if (chan->writetrans)
01864       ast_translator_free_path(chan->writetrans);
01865    if (chan->pbx)
01866       ast_log(LOG_WARNING, "PBX may not have been terminated properly on '%s'\n", chan->name);
01867 
01868    free_cid(&chan->cid);
01869    ast_party_connected_line_free(&chan->connected);
01870    ast_party_redirecting_free(&chan->redirecting);
01871 
01872    /* Close pipes if appropriate */
01873    if ((fd = chan->alertpipe[0]) > -1)
01874       close(fd);
01875    if ((fd = chan->alertpipe[1]) > -1)
01876       close(fd);
01877    if (chan->timer) {
01878       ast_timer_close(chan->timer);
01879    }
01880 #ifdef HAVE_EPOLL
01881    for (i = 0; i < AST_MAX_FDS; i++) {
01882       if (chan->epfd_data[i])
01883          free(chan->epfd_data[i]);
01884    }
01885    close(chan->epfd);
01886 #endif
01887    while ((f = AST_LIST_REMOVE_HEAD(&chan->readq, frame_list)))
01888       ast_frfree(f);
01889    
01890    /* loop over the variables list, freeing all data and deleting list items */
01891    /* no need to lock the list, as the channel is already locked */
01892    
01893    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
01894       ast_var_delete(vardata);
01895 
01896    ast_app_group_discard(chan);
01897 
01898    /* Destroy the jitterbuffer */
01899    ast_jb_destroy(chan);
01900 
01901    if (chan->cdr) {
01902       ast_cdr_discard(chan->cdr);
01903       chan->cdr = NULL;
01904    }
01905 
01906    if (chan->zone) {
01907       chan->zone = ast_tone_zone_unref(chan->zone);
01908    }
01909 
01910    ast_string_field_free_memory(chan);
01911 
01912    /* Queue an unknown state, because, while we know that this particular
01913     * instance is dead, we don't know the state of all other possible
01914     * instances. */
01915    ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, name);
01916 }

int ast_channel_early_bridge ( struct ast_channel c0,
struct ast_channel c1 
)

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

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

Referenced by dial_exec_full(), and wait_for_answer().

05739 {
05740    /* Make sure we can early bridge, if not error out */
05741    if (!c0->tech->early_bridge || (c1 && (!c1->tech->early_bridge || c0->tech->early_bridge != c1->tech->early_bridge)))
05742       return -1;
05743 
05744    return c0->tech->early_bridge(c0, c1);
05745 }

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

Find a channel by extension and context.

  • exten the extension to search for
  • context the context to search for (optional)
Return a channel that is currently at the specified extension and context.

Return values:
a channel that is at the specified extension and context
NULL if no channel was found
Since:
1.6.3

Definition at line 1407 of file channel.c.

References ast_channel_get_full().

01408 {
01409    return ast_channel_get_full(NULL, 0, exten, context);
01410 }

struct ast_channel* ast_channel_get_by_name ( const char *  name  )  [read]

struct ast_channel* ast_channel_get_by_name_prefix ( const char *  name,
size_t  name_len 
) [read]

Find a channel by a name prefix.

  • name The channel name or uniqueid prefix to search for
  • name_len Only search for up to this many characters from the name
Find a channel that has the same name prefix as specified by the arguments.

Return values:
a channel with the name prefix specified by the arguments
NULL if no channel was found
Since:
1.6.3

Definition at line 1402 of file channel.c.

References ast_channel_get_full().

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

01403 {
01404    return ast_channel_get_full(name, name_len, NULL, NULL);
01405 }

static struct ast_channel* ast_channel_get_full ( const char *  name,
size_t  name_len,
const char *  exten,
const char *  context 
) [static, read]

Definition at line 1355 of file channel.c.

References ao2_find, ast_copy_string(), ast_strlen_zero(), channels, ast_channel::context, ast_channel::exten, ast_channel::name, OBJ_POINTER, and ast_channel::uniqueid.

Referenced by ast_channel_get_by_exten(), ast_channel_get_by_name(), and ast_channel_get_by_name_prefix().

01357 {
01358    struct ast_channel tmp_chan = {
01359       .name = name,
01360       /* This is sort of a hack.  Basically, we're using an arbitrary field
01361        * in ast_channel to pass the name_len for a prefix match.  If this
01362        * gets changed, then the compare callback must be changed, too. */
01363       .rings = name_len,
01364    };
01365    struct ast_channel *chan;
01366 
01367    if (exten) {
01368       ast_copy_string(tmp_chan.exten, exten, sizeof(tmp_chan.exten));
01369    }
01370 
01371    if (context) {
01372       ast_copy_string(tmp_chan.context, context, sizeof(tmp_chan.context));
01373    }
01374 
01375    if ((chan = ao2_find(channels, &tmp_chan,
01376               (!ast_strlen_zero(name) && (name_len == 0)) ? OBJ_POINTER : 0))) {
01377       return chan;
01378    }
01379 
01380    if (!name) {
01381       return NULL;
01382    }
01383 
01384    /* If name was specified, but the result was NULL, 
01385     * try a search on uniqueid, instead. */
01386 
01387    {
01388       struct ast_channel tmp_chan2 = {
01389          .uniqueid = name,
01390          .rings = name_len,
01391       };
01392 
01393       return ao2_find(channels, &tmp_chan2, 0);
01394    }
01395 }

static int ast_channel_hash_cb ( const void *  obj,
const int  flags 
) [static]

Definition at line 6353 of file channel.c.

References ast_str_case_hash(), ast_strlen_zero(), and ast_channel::name.

06354 {
06355    const struct ast_channel *chan = obj;
06356 
06357    /* If the name isn't set, return 0 so that the ao2_find() search will
06358     * start in the first bucket. */
06359    if (ast_strlen_zero(chan->name)) {
06360       return 0;
06361    }
06362 
06363    return ast_str_case_hash(chan->name);
06364 }

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 4851 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(), ast_var_t::entries, and ast_channel::varshead.

Referenced by __ast_request_and_dial(), ast_call_forward(), begin_dial_channel(), dial_exec_full(), dial_transfer(), do_forward(), feature_request_and_dial(), findmeexec(), ring_entry(), and wait_for_answer().

04852 {
04853    struct ast_var_t *current, *newvar;
04854    const char *varname;
04855 
04856    AST_LIST_TRAVERSE(&parent->varshead, current, entries) {
04857       int vartype = 0;
04858 
04859       varname = ast_var_full_name(current);
04860       if (!varname)
04861          continue;
04862 
04863       if (varname[0] == '_') {
04864          vartype = 1;
04865          if (varname[1] == '_')
04866             vartype = 2;
04867       }
04868 
04869       switch (vartype) {
04870       case 1:
04871          newvar = ast_var_assign(&varname[1], ast_var_value(current));
04872          if (newvar) {
04873             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
04874             ast_debug(1, "Copying soft-transferable variable %s.\n", ast_var_name(newvar));
04875          }
04876          break;
04877       case 2:
04878          newvar = ast_var_assign(varname, ast_var_value(current));
04879          if (newvar) {
04880             AST_LIST_INSERT_TAIL(&child->varshead, newvar, entries);
04881             ast_debug(1, "Copying hard-transferable variable %s.\n", ast_var_name(newvar));
04882          }
04883          break;
04884       default:
04885          ast_debug(1, "Not copying variable %s.\n", ast_var_name(current));
04886          break;
04887       }
04888    }
04889 }

struct ast_channel_iterator* ast_channel_iterator_all_new ( void   )  [read]

Create a new channel iterator.

After creating an iterator using this function, the ast_channel_iterator_next() function can be used to iterate through all channels that exist.

Return values:
NULL on failure
a new channel iterator
Since:
1.6.3

Definition at line 1297 of file channel.c.

References ast_channel_iterator::active_iterator, ao2_iterator_init(), ast_calloc, channels, and ast_channel_iterator::simple_iterator.

Referenced by action_coreshowchannels(), action_status(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), common_exec(), func_channels_read(), and handle_chanlist().

01298 {
01299    struct ast_channel_iterator *i;
01300 
01301    if (!(i = ast_calloc(1, sizeof(*i)))) {
01302       return NULL;
01303    }
01304 
01305    i->simple_iterator = ao2_iterator_init(channels, 0);
01306    i->active_iterator = &i->simple_iterator;
01307 
01308    return i;
01309 }

struct ast_channel_iterator* ast_channel_iterator_by_exten_new ( const char *  exten,
const char *  context 
) [read]

Create a new channel iterator based on extension.

  • exten The extension that channels must be in
  • context The context that channels must be in (optional)
After creating an iterator using this function, the ast_channel_iterator_next() function can be used to iterate through all channels that are currently in the specified context and extension.

Return values:
NULL on failure
a new channel iterator based on the specified parameters
Since:
1.6.3

Definition at line 1287 of file channel.c.

References channel_iterator_search().

Referenced by common_exec(), and pickup_by_exten().

01288 {
01289    return channel_iterator_search(NULL, 0, exten, context);
01290 }

struct ast_channel_iterator* ast_channel_iterator_by_name_new ( const char *  name,
size_t  name_len 
) [read]

Create a new channel iterator based on name.

  • name channel name or channel uniqueid to match
  • name_len number of characters in the channel name to match on. This would be used to match based on name prefix. If matching on the full channel name is desired, then this parameter should be 0.
After creating an iterator using this function, the ast_channel_iterator_next() function can be used to iterate through all channels that exist that have the specified name or name prefix.

Return values:
NULL on failure
a new channel iterator based on the specified parameters
Since:
1.6.3

Definition at line 1292 of file channel.c.

References channel_iterator_search().

Referenced by ast_complete_channels(), common_exec(), and softhangup_exec().

01293 {
01294    return channel_iterator_search(name, name_len, NULL, NULL);
01295 }

struct ast_channel_iterator* ast_channel_iterator_destroy ( struct ast_channel_iterator i  )  [read]

Destroy a channel iterator.

  • i the itereator to destroy
This function is used to destroy a channel iterator that was retrieved by using one of the channel_iterator_new() functions.

Returns:
NULL, for convenience to clear out the pointer to the iterator that was just destroyed.
Since:
1.6.3

Definition at line 1245 of file channel.c.

References ast_channel_iterator::active_iterator, ao2_iterator_destroy(), and ast_free.

Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), common_exec(), func_channels_read(), handle_chanlist(), pickup_by_exten(), and softhangup_exec().

01246 {
01247    ao2_iterator_destroy(i->active_iterator);
01248    ast_free(i);
01249 
01250    return NULL;
01251 }

struct ast_channel* ast_channel_iterator_next ( struct ast_channel_iterator i  )  [read]

Get the next channel for a channel iterator.

  • i the channel iterator that was created using one of the channel_iterator_new() functions.
This function should be used to iterate through all channels that match a specified set of parameters that were provided when the iterator was created.

Return values:
the next channel that matches the parameters used when the iterator was created.
NULL,if no more channels match the iterator parameters.
Since:
1.6.3

Definition at line 1311 of file channel.c.

References ast_channel_iterator::active_iterator, and ao2_iterator_next.

Referenced by action_coreshowchannels(), action_status(), ast_complete_channels(), ast_var_channel_bridge(), ast_var_channel_types_table(), ast_var_channels_table(), func_channels_read(), handle_chanlist(), next_channel(), pickup_by_exten(), and softhangup_exec().

01312 {
01313    return ao2_iterator_next(i->active_iterator);
01314 }

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 4735 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(), multiplexed_bridge_join(), park_exec_full(), simple_bridge_join(), try_calling(), and wait_for_answer().

04736 {
04737    /* Some callers do not check return code, and we must try to set all call legs correctly */
04738    int rc = 0;
04739 
04740    /* Set up translation from the chan to the peer */
04741    rc = ast_channel_make_compatible_helper(chan, peer);
04742 
04743    if (rc < 0)
04744       return rc;
04745 
04746    /* Set up translation from the peer to the chan */
04747    rc = ast_channel_make_compatible_helper(peer, chan);
04748 
04749    return rc;
04750 }

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

References ast_channel_setoption(), AST_FORMAT_AUDIO_MASK, AST_FORMAT_SLINEAR, ast_log(), ast_opt_transcode_via_slin, AST_OPTION_MAKE_COMPATIBLE, ast_set_read_format(), ast_set_write_format(), ast_translate_path_steps(), ast_translator_best_choice(), ast_channel_tech::bridge, LOG_WARNING, ast_channel::name, ast_channel::nativeformats, ast_channel::readformat, ast_frame::src, ast_channel::tech, and ast_channel::writeformat.

Referenced by ast_channel_make_compatible().

04689 {
04690    int src;
04691    int dst;
04692 
04693    /* See if the channel driver can natively make these two channels compatible */
04694    if (from->tech->bridge && from->tech->bridge == to->tech->bridge &&
04695        !ast_channel_setoption(from, AST_OPTION_MAKE_COMPATIBLE, to, sizeof(struct ast_channel *), 0)) {
04696       return 0;
04697    }
04698 
04699    if (from->readformat == to->writeformat && from->writeformat == to->readformat) {
04700       /* Already compatible!  Moving on ... */
04701       return 0;
04702    }
04703 
04704    /* Set up translation from the 'from' channel to the 'to' channel */
04705    src = from->nativeformats;
04706    dst = to->nativeformats;
04707 
04708    /* If there's no audio in this call, don't bother with trying to find a translation path */
04709    if ((src & AST_FORMAT_AUDIO_MASK) == 0 || (dst & AST_FORMAT_AUDIO_MASK) == 0)
04710       return 0;
04711 
04712    if (ast_translator_best_choice(&dst, &src) < 0) {
04713       ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", from->name, src, to->name, dst);
04714       return -1;
04715    }
04716 
04717    /* if the best path is not 'pass through', then
04718       transcoding is needed; if desired, force transcode path
04719       to use SLINEAR between channels, but only if there is
04720       no direct conversion available */
04721    if ((src != dst) && ast_opt_transcode_via_slin &&
04722        (ast_translate_path_steps(dst, src) != 1))
04723       dst = AST_FORMAT_SLINEAR;
04724    if (ast_set_read_format(from, dst) < 0) {
04725       ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", from->name, dst);
04726       return -1;
04727    }
04728    if (ast_set_write_format(to, dst) < 0) {
04729       ast_log(LOG_WARNING, "Unable to set write format on channel %s to %d\n", to->name, dst);
04730       return -1;
04731    }
04732    return 0;
04733 }

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

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

04753 {
04754    int res = -1;
04755    struct ast_channel *final_orig, *final_clone, *base;
04756 
04757 retrymasq:
04758    final_orig = original;
04759    final_clone = clonechan;
04760 
04761    ast_channel_lock(original);
04762    while (ast_channel_trylock(clonechan)) {
04763       ast_channel_unlock(original);
04764       usleep(1);
04765       ast_channel_lock(original);
04766    }
04767 
04768    /* each of these channels may be sitting behind a channel proxy (i.e. chan_agent)
04769       and if so, we don't really want to masquerade it, but its proxy */
04770    if (original->_bridge && (original->_bridge != ast_bridged_channel(original)) && (original->_bridge->_bridge != original))
04771       final_orig = original->_bridge;
04772 
04773    if (clonechan->_bridge && (clonechan->_bridge != ast_bridged_channel(clonechan)) && (clonechan->_bridge->_bridge != clonechan))
04774       final_clone = clonechan->_bridge;
04775    
04776    if (final_clone->tech->get_base_channel && (base = final_clone->tech->get_base_channel(final_clone))) {
04777       final_clone = base;
04778    }
04779 
04780    if ((final_orig != original) || (final_clone != clonechan)) {
04781       /* Lots and lots of deadlock avoidance.  The main one we're competing with
04782        * is ast_write(), which locks channels recursively, when working with a
04783        * proxy channel. */
04784       if (ast_channel_trylock(final_orig)) {
04785          ast_channel_unlock(clonechan);
04786          ast_channel_unlock(original);
04787          goto retrymasq;
04788       }
04789       if (ast_channel_trylock(final_clone)) {
04790          ast_channel_unlock(final_orig);
04791          ast_channel_unlock(clonechan);
04792          ast_channel_unlock(original);
04793          goto retrymasq;
04794       }
04795       ast_channel_unlock(clonechan);
04796       ast_channel_unlock(original);
04797       original = final_orig;
04798       clonechan = final_clone;
04799    }
04800 
04801    if (original == clonechan) {
04802       ast_log(LOG_WARNING, "Can't masquerade channel '%s' into itself!\n", original->name);
04803       ast_channel_unlock(clonechan);
04804       ast_channel_unlock(original);
04805       return -1;
04806    }
04807 
04808    ast_debug(1, "Planning to masquerade channel %s into the structure of %s\n",
04809       clonechan->name, original->name);
04810    if (original->masq) {
04811       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
04812          original->masq->name, original->name);
04813    } else if (clonechan->masqr) {
04814       ast_log(LOG_WARNING, "%s is already going to masquerade as %s\n",
04815          clonechan->name, clonechan->masqr->name);
04816    } else {
04817       original->masq = clonechan;
04818       clonechan->masqr = original;
04819       ast_queue_frame(original, &ast_null_frame);
04820       ast_queue_frame(clonechan, &ast_null_frame);
04821       ast_debug(1, "Done planning to masquerade channel %s into the structure of %s\n", clonechan->name, original->name);
04822       res = 0;
04823    }
04824 
04825    ast_channel_unlock(clonechan);
04826    ast_channel_unlock(original);
04827 
04828    return res;
04829 }

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 6112 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(), rcvfax_exec(), and sndfax_exec().

06113 {
06114    if (!chan->tech->queryoption) {
06115       errno = ENOSYS;
06116       return -1;
06117    }
06118 
06119    if (block)
06120       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
06121 
06122    return chan->tech->queryoption(chan, option, data, datalen);
06123 }

void ast_channel_queue_connected_line_update ( struct ast_channel chan,
const struct ast_party_connected_line connected 
)

Queue a connected line update frame on a channel.

Since:
1.6.3
Parameters:
chan Asterisk channel to indicate connected line information
connected Connected line information
Returns:
Nothing

Definition at line 6896 of file channel.c.

References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, and ast_queue_control_data().

Referenced by ast_pickup_call(), handle_request_invite(), handle_request_update(), handle_response_invite(), local_attended_transfer(), misdn_queue_connected_line_update(), and pickup_do().

06897 {
06898    unsigned char data[1024];  /* This should be large enough */
06899    size_t datalen;
06900 
06901    datalen = ast_connected_line_build_data(data, sizeof(data), connected);
06902    if (datalen == (size_t) -1) {
06903       return;
06904    }
06905 
06906    ast_queue_control_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
06907 }

void ast_channel_queue_redirecting_update ( struct ast_channel chan,
const struct ast_party_redirecting redirecting 
)

Queue a redirecting update frame on a channel.

Since:
1.6.3
Parameters:
chan Asterisk channel to indicate redirecting id information
redirecting Redirecting id information
Returns:
Nothing

Definition at line 7353 of file channel.c.

References AST_CONTROL_REDIRECTING, ast_queue_control_data(), and ast_redirecting_build_data().

Referenced by cb_events(), handle_response_invite(), and misdn_facility_ie_handler().

07354 {
07355    unsigned char data[1024];  /* This should be large enough */
07356    size_t datalen;
07357 
07358    datalen = ast_redirecting_build_data(data, sizeof(data), redirecting);
07359    if (datalen == (size_t) -1) {
07360       return;
07361    }
07362 
07363    ast_queue_control_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
07364 }

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

04231 {
04232    switch (reason) /* the following appear to be the only ones actually returned by request_and_dial */
04233    {
04234    case 0:
04235       return "Call Failure (not BUSY, and not NO_ANSWER, maybe Circuit busy or down?)";
04236    case AST_CONTROL_HANGUP:
04237       return "Hangup";
04238    case AST_CONTROL_RING:
04239       return "Local Ring";
04240    case AST_CONTROL_RINGING:
04241       return "Remote end Ringing";
04242    case AST_CONTROL_ANSWER:
04243       return "Remote end has Answered";
04244    case AST_CONTROL_BUSY:
04245       return "Remote end is Busy";
04246    case AST_CONTROL_CONGESTION:
04247       return "Congestion (circuits busy)";
04248    default:
04249       return "Unknown Reason!!";
04250    }
04251 }

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

References ast_calloc, ast_debug, ast_log(), AST_RWLIST_INSERT_HEAD, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, AST_RWLIST_WRLOCK, ast_verb, ast_channel_tech::description, LOG_WARNING, chanlist::tech, and ast_channel_tech::type.

Referenced by load_module(), and unload_module().

00568 {
00569    struct chanlist *chan;
00570 
00571    AST_RWLIST_WRLOCK(&backends);
00572 
00573    AST_RWLIST_TRAVERSE(&backends, chan, list) {
00574       if (!strcasecmp(tech->type, chan->tech->type)) {
00575          ast_log(LOG_WARNING, "Already have a handler for type '%s'\n", tech->type);
00576          AST_RWLIST_UNLOCK(&backends);
00577          return -1;
00578       }
00579    }
00580    
00581    if (!(chan = ast_calloc(1, sizeof(*chan)))) {
00582       AST_RWLIST_UNLOCK(&backends);
00583       return -1;
00584    }
00585    chan->tech = tech;
00586    AST_RWLIST_INSERT_HEAD(&backends, chan, list);
00587 
00588    ast_debug(1, "Registered handler for '%s' (%s)\n", chan->tech->type, chan->tech->description);
00589 
00590    ast_verb(2, "Registered channel type '%s' (%s)\n", chan->tech->type, chan->tech->description);
00591 
00592    AST_RWLIST_UNLOCK(&backends);
00593 
00594    return 0;
00595 }

struct ast_channel* ast_channel_release ( struct ast_channel chan  )  [read]

Unlink and release reference to a channel.

This function will unlink the channel from the global channels container if it is still there and also release the current reference to the channel.

Returns:
NULL, convenient for clearing invalid pointers
Since:
1.6.3

Definition at line 1456 of file channel.c.

References ao2_unlink, ast_channel_unref, and channels.

Referenced by acf_odbc_read(), acf_odbc_write(), action_getvar(), agent_cleanup(), agent_new(), ast_add_extension2_lockopt(), ast_cel_fabricate_channel_from_event(), ast_do_masquerade(), ast_hangup(), ast_iax2_new(), ast_pbx_outgoing_cdr_failed(), ast_str_substitute_variables_full(), bridge_request(), cli_odbc_read(), cli_odbc_write(), custom_log(), do_notify(), gtalk_newcall(), local_new(), make_email_file(), manager_log(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), sendpage(), sqlite3_log(), and syslog_log().

01457 {
01458    /* Safe, even if already unlinked. */
01459    ao2_unlink(channels, chan);
01460    return ast_channel_unref(chan);
01461 }

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

04676 {
04677    if (chan->tech->send_html)
04678       return chan->tech->send_html(chan, subclass, data, datalen);
04679    return -1;
04680 }

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

References ast_channel_sendhtml(), and AST_HTML_URL.

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

04683 {
04684    return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
04685 }

void ast_channel_set_connected_line ( struct ast_channel chan,
const struct ast_party_connected_line connected 
)

Set the connected line information in the Asterisk channel.

Since:
1.6.3
Parameters:
chan Asterisk channel to set connected line information
connected Connected line information
Returns:
Nothing
Note:
The channel does not need to be locked before calling this function.

Definition at line 6643 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_party_connected_line_set(), and ast_channel::connected.

Referenced by __ast_request_and_dial(), ast_indicate_data(), and connectedline_write().

06644 {
06645    if (&chan->connected == connected) {
06646       /* Don't set to self */
06647       return;
06648    }
06649 
06650    ast_channel_lock(chan);
06651    ast_party_connected_line_set(&chan->connected, connected);
06652    ast_channel_unlock(chan);
06653 }

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

Set the file descriptor on the channel

Definition at line 2011 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(), my_swap_subchannels(), nbs_new(), oss_new(), phone_new(), setformat(), sip_new(), skinny_new(), start_rtp(), and swap_subs().

02012 {
02013 #ifdef HAVE_EPOLL
02014    struct epoll_event ev;
02015    struct ast_epoll_data *aed = NULL;
02016 
02017    if (chan->fds[which] > -1) {
02018       epoll_ctl(chan->epfd, EPOLL_CTL_DEL, chan->fds[which], &ev);
02019       aed = chan->epfd_data[which];
02020    }
02021 
02022    /* If this new fd is valid, add it to the epoll */
02023    if (fd > -1) {
02024       if (!aed && (!(aed = ast_calloc(1, sizeof(*aed)))))
02025          return;
02026       
02027       chan->epfd_data[which] = aed;
02028       aed->chan = chan;
02029       aed->which = which;
02030       
02031       ev.events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
02032       ev.data.ptr = aed;
02033       epoll_ctl(chan->epfd, EPOLL_CTL_ADD, fd, &ev);
02034    } else if (aed) {
02035       /* We don't have to keep around this epoll data structure now */
02036       free(aed);
02037       chan->epfd_data[which] = NULL;
02038    }
02039 #endif
02040    chan->fds[which] = fd;
02041    return;
02042 }

void ast_channel_set_linkgroup ( struct ast_channel chan,
struct ast_channel peer 
)

Propagate the oldest linkedid between associated channels.

propagate the linked id between chan and peer

Definition at line 4995 of file channel.c.

References ast_channel::_bridge, ast_bridged_channel(), ast_channel_change_linkedid(), ast_strdupa, ast_channel::linkedid, oldest_linkedid(), and ast_channel::uniqueid.

Referenced by ast_bridge_call(), and ast_do_masquerade().

04996 {
04997    const char* linkedid=NULL;
04998    struct ast_channel *bridged;
04999 
05000    linkedid = oldest_linkedid(chan->linkedid, peer->linkedid);
05001    linkedid = oldest_linkedid(linkedid, chan->uniqueid);
05002    linkedid = oldest_linkedid(linkedid, peer->uniqueid);
05003    if (chan->_bridge) {
05004       bridged = ast_bridged_channel(chan);
05005       if (bridged != peer) {
05006          linkedid = oldest_linkedid(linkedid, bridged->linkedid);
05007          linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
05008       }
05009    }
05010    if (peer->_bridge) {
05011       bridged = ast_bridged_channel(peer);
05012       if (bridged != chan) {
05013          linkedid = oldest_linkedid(linkedid, bridged->linkedid);
05014          linkedid = oldest_linkedid(linkedid, bridged->uniqueid);
05015       }
05016    }
05017 
05018    /* just in case setting a stringfield to itself causes problems */
05019    linkedid = ast_strdupa(linkedid);
05020 
05021    ast_channel_change_linkedid(chan, linkedid);
05022    ast_channel_change_linkedid(peer, linkedid);
05023    if (chan->_bridge) {
05024       bridged = ast_bridged_channel(chan);
05025       if (bridged != peer) {
05026          ast_channel_change_linkedid(bridged, linkedid);
05027       }
05028    }
05029    if (peer->_bridge) {
05030       bridged = ast_bridged_channel(peer);
05031       if (bridged != chan) {
05032          ast_channel_change_linkedid(bridged, linkedid);
05033       }
05034    }
05035 }

void ast_channel_set_redirecting ( struct ast_channel chan,
const struct ast_party_redirecting redirecting 
)

Set the redirecting id information in the Asterisk channel.

Since:
1.6.3
Parameters:
chan Asterisk channel to set redirecting id information
redirecting Redirecting id information
Returns:
Nothing
Note:
The channel does not need to be locked before calling this function.

Definition at line 6909 of file channel.c.

References ast_channel_lock, ast_channel_unlock, ast_free, ast_party_id_set(), ast_channel::cid, ast_callerid::cid_rdnis, ast_party_redirecting::count, ast_party_redirecting::from, ast_party_id::number, ast_party_redirecting::reason, ast_channel::redirecting, and ast_party_redirecting::to.

Referenced by ast_call_forward(), ast_indicate_data(), do_forward(), handle_request_invite(), handle_response(), misdn_copy_redirecting_to_ast(), redirecting_write(), and wait_for_answer().

06910 {
06911    if (&chan->redirecting == redirecting) {
06912       /* Don't set to self */
06913       return;
06914    }
06915 
06916    ast_channel_lock(chan);
06917 
06918    ast_party_id_set(&chan->redirecting.from, &redirecting->from);
06919    if (redirecting->from.number
06920       && redirecting->from.number != chan->redirecting.from.number) {
06921       /*
06922        * Must move string to ast_channel.cid.cid_rdnis until it goes away.
06923        */
06924       if (chan->cid.cid_rdnis) {
06925          ast_free(chan->cid.cid_rdnis);
06926       }
06927       chan->cid.cid_rdnis = chan->redirecting.from.number;
06928       chan->redirecting.from.number = NULL;
06929    }
06930 
06931    ast_party_id_set(&chan->redirecting.to, &redirecting->to);
06932    chan->redirecting.reason = redirecting->reason;
06933    chan->redirecting.count = redirecting->count;
06934 
06935    ast_channel_unlock(chan);
06936 }

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

Sets an option on a channel.

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

Definition at line 6099 of file channel.c.

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

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

06100 {
06101    if (!chan->tech->setoption) {
06102       errno = ENOSYS;
06103       return -1;
06104    }
06105 
06106    if (block)
06107       ast_log(LOG_ERROR, "XXX Blocking not implemented yet XXX\n");
06108 
06109    return chan->tech->setoption(chan, option, data, datalen);
06110 }

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

References ast_channel_setwhentohangup_tv().

00539 {
00540    struct timeval when = { offset, };
00541    ast_channel_setwhentohangup_tv(chan, when);
00542 }

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

00532 {
00533    chan->whentohangup = ast_tvzero(offset) ? offset : ast_tvadd(offset, ast_tvnow());
00534    ast_queue_frame(chan, &ast_null_frame);
00535    return;
00536 }

static int ast_channel_softhangup_cb ( void *  obj,
void *  arg,
int  flags 
) [static]

Definition at line 494 of file channel.c.

References ast_softhangup(), and AST_SOFTHANGUP_SHUTDOWN.

Referenced by ast_begin_shutdown().

00495 {
00496    struct ast_channel *chan = obj;
00497 
00498    ast_softhangup(chan, AST_SOFTHANGUP_SHUTDOWN);
00499 
00500    return 0;
00501 }

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.

Note:
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 6448 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_channel::name, ast_silence_generator::old_write_format, and ast_channel::writeformat.

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

06449 {
06450    struct ast_silence_generator *state;
06451 
06452    if (!(state = ast_calloc(1, sizeof(*state)))) {
06453       return NULL;
06454    }
06455 
06456    state->old_write_format = chan->writeformat;
06457 
06458    if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
06459       ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
06460       ast_free(state);
06461       return NULL;
06462    }
06463 
06464    ast_activate_generator(chan, &silence_generator, state);
06465 
06466    ast_debug(1, "Started silence generator on '%s'\n", chan->name);
06467 
06468    return state;
06469 }

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

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

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

06472 {
06473    if (!state)
06474       return;
06475 
06476    ast_deactivate_generator(chan);
06477 
06478    ast_debug(1, "Stopped silence generator on '%s'\n", chan->name);
06479 
06480    if (ast_set_write_format(chan, state->old_write_format) < 0)
06481       ast_log(LOG_ERROR, "Could not return write format to its original state\n");
06482 
06483    ast_free(state);
06484 }

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

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

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

04671 {
04672    return (chan->tech->send_html) ? 1 : 0;
04673 }

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

References ast_clear_flag, and AST_FLAG_DEFER_DTMF.

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

01225 {
01226    if (chan)
01227       ast_clear_flag(chan, AST_FLAG_DEFER_DTMF);
01228 }

void ast_channel_unregister ( const struct ast_channel_tech tech  ) 

Unregister channel driver.

Unregister a channel technology.

Definition at line 598 of file channel.c.

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

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

00599 {
00600    struct chanlist *chan;
00601 
00602    ast_debug(1, "Unregistering channel type '%s'\n", tech->type);
00603 
00604    AST_RWLIST_WRLOCK(&backends);
00605 
00606    AST_RWLIST_TRAVERSE_SAFE_BEGIN(&backends, chan, list) {
00607       if (chan->tech == tech) {
00608          AST_LIST_REMOVE_CURRENT(list);
00609          ast_free(chan);
00610          ast_verb(2, "Unregistered channel type '%s'\n", tech->type);
00611          break;   
00612       }
00613    }
00614    AST_LIST_TRAVERSE_SAFE_END;
00615 
00616    AST_RWLIST_UNLOCK(&backends);
00617 }

void ast_channel_update_connected_line ( struct ast_channel chan,
const struct ast_party_connected_line connected 
)

Indicate that the connected line information has changed.

Since:
1.6.3
Parameters:
chan Asterisk channel to indicate connected line information
connected Connected line information
Returns:
Nothing

Definition at line 6883 of file channel.c.

References ast_connected_line_build_data(), AST_CONTROL_CONNECTED_LINE, and ast_indicate_data().

Referenced by ast_channel_connected_line_macro(), ast_pickup_call(), builtin_atxfer(), builtin_blindtransfer(), connectedline_write(), local_attended_transfer(), pickup_do(), and wait_for_answer().

06884 {
06885    unsigned char data[1024];  /* This should be large enough */
06886    size_t datalen;
06887 
06888    datalen = ast_connected_line_build_data(data, sizeof(data), connected);
06889    if (datalen == (size_t) -1) {
06890       return;
06891    }
06892 
06893    ast_indicate_data(chan, AST_CONTROL_CONNECTED_LINE, data, datalen);
06894 }

void ast_channel_update_redirecting ( struct ast_channel chan,
const struct ast_party_redirecting redirecting 
)

Indicate that the redirecting id has changed.

Since:
1.6.3
Parameters:
chan Asterisk channel to indicate redirecting id information
redirecting Redirecting id information
Returns:
Nothing

Definition at line 7340 of file channel.c.

References AST_CONTROL_REDIRECTING, ast_indicate_data(), and ast_redirecting_build_data().

Referenced by ast_call_forward(), do_forward(), redirecting_write(), and wait_for_answer().

07341 {
07342    unsigned char data[1024];  /* This should be large enough */
07343    size_t datalen;
07344 
07345    datalen = ast_redirecting_build_data(data, sizeof(data), redirecting);
07346    if (datalen == (size_t) -1) {
07347       return;
07348    }
07349 
07350    ast_indicate_data(chan, AST_CONTROL_REDIRECTING, data, datalen);
07351 }

void ast_channels_init ( void   ) 

struct ast_variable* ast_channeltype_list ( void   )  [read]

return an ast_variable list of channeltypes

Definition at line 193 of file channel.c.

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, ast_variable_new(), ast_channel_tech::description, chanlist::tech, ast_channel_tech::type, and var.

Referenced by ast_var_channel_types(), and ast_var_channel_types_table().

00194 {
00195    struct chanlist *cl;
00196    struct ast_variable *var = NULL, *prev = NULL;
00197 
00198    AST_RWLIST_RDLOCK(&backends);
00199    AST_RWLIST_TRAVERSE(&backends, cl, list) {
00200       if (prev)  {
00201          if ((prev->next = ast_variable_new(cl->tech->type, cl->tech->description, "")))
00202             prev = prev->next;
00203       } else {
00204          var = ast_variable_new(cl->tech->type, cl->tech->description, "");
00205          prev = var;
00206       }
00207    }
00208    AST_RWLIST_UNLOCK(&backends);
00209 
00210    return var;
00211 }

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 473 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(), agent_indicate(), agi_exec(), agi_handle_command(), announce_thread(), ast_bridge_call(), ast_call(), ast_channel_bridge(), ast_check_hangup_locked(), ast_indicate_data(), ast_raw_answer(), ast_readstring_full(), ast_recvtext(), ast_rtp_instance_bridge(), ast_sendtext(), ast_transfer(), ast_udptl_bridge(), ast_waitfordigit_full(), ast_write(), autoservice_run(), bridge_call_thread(), bridge_exec(), 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(), feature_request_and_dial(), findmeexec(), handle_sendimage(), iax2_bridge(), launch_asyncagi(), local_bridge_loop(), lua_check_hangup(), ospfinished_exec(), pbx_builtin_incomplete(), pbx_exec(), read_exec(), readexten_exec(), remote_bridge_loop(), rpt(), rpt_exec(), run_ras(), try_calling(), and wait_for_answer().

00474 {
00475    if (chan->_softhangup)     /* yes if soft hangup flag set */
00476       return 1;
00477    if (ast_tvzero(chan->whentohangup)) /* no if no hangup scheduled */
00478       return 0;
00479    if (ast_tvdiff_ms(chan->whentohangup, ast_tvnow()) > 0)  /* no if hangup time has not come yet. */
00480       return 0;
00481    chan->_softhangup |= AST_SOFTHANGUP_TIMEOUT; /* record event */
00482    return 1;
00483 }

int ast_check_hangup_locked ( struct ast_channel chan  ) 

Definition at line 485 of file channel.c.

References ast_channel_lock, ast_channel_unlock, and ast_check_hangup().

Referenced by action_redirect(), and ast_channel_bridge().

00486 {
00487    int res;
00488    ast_channel_lock(chan);
00489    res = ast_check_hangup(chan);
00490    ast_channel_unlock(chan);
00491    return res;
00492 }

int ast_connected_line_build_data ( unsigned char *  data,
size_t  datalen,
const struct ast_party_connected_line connected 
)

Build the connected line information data frame.

Since:
1.6.3
Parameters:
data Buffer to fill with the frame data
datalen Size of the buffer to fill
connected Connected line information
Return values:
-1 if error
Amount of data buffer used

Definition at line 6671 of file channel.c.

References AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NUMBER_PRESENTATION, AST_CONNECTED_LINE_NUMBER_TYPE, AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_VALID, ast_log(), ast_party_connected_line::id, LOG_WARNING, ast_party_id::name, ast_party_id::number, ast_party_id::number_presentation, ast_party_id::number_type, ast_party_subaddress::odd_even_indicator, ast_party_connected_line::source, ast_party_subaddress::str, ast_party_id::subaddress, ast_party_subaddress::type, ast_party_subaddress::valid, and value.

Referenced by ast_channel_queue_connected_line_update(), ast_channel_update_connected_line(), and local_indicate().

06672 {
06673    int32_t value;
06674    size_t length;
06675    size_t pos = 0;
06676 
06677    /*
06678     * The size of integer values must be fixed in case the frame is
06679     * shipped to another machine.
06680     */
06681 
06682    /* *************** Connected line party id *************** */
06683    if (connected->id.number) {
06684       length = strlen(connected->id.number);
06685       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
06686          ast_log(LOG_WARNING, "No space left for connected line number\n");
06687          return -1;
06688       }
06689       data[pos++] = AST_CONNECTED_LINE_NUMBER;
06690       data[pos++] = length;
06691       memcpy(data + pos, connected->id.number, length);
06692       pos += length;
06693    }
06694 
06695    if (connected->id.name) {
06696       length = strlen(connected->id.name);
06697       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
06698          ast_log(LOG_WARNING, "No space left for connected line name\n");
06699          return -1;
06700       }
06701       data[pos++] = AST_CONNECTED_LINE_NAME;
06702       data[pos++] = length;
06703       memcpy(data + pos, connected->id.name, length);
06704       pos += length;
06705    }
06706 
06707    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
06708       ast_log(LOG_WARNING, "No space left for connected line type of number\n");
06709       return -1;
06710    }
06711    data[pos++] = AST_CONNECTED_LINE_NUMBER_TYPE;
06712    data[pos++] = 1;
06713    data[pos++] = connected->id.number_type;
06714 
06715    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
06716       ast_log(LOG_WARNING, "No space left for connected line presentation\n");
06717       return -1;
06718    }
06719    data[pos++] = AST_CONNECTED_LINE_NUMBER_PRESENTATION;
06720    data[pos++] = 1;
06721    data[pos++] = connected->id.number_presentation;
06722 
06723    /* Connected line source */
06724    if (datalen < pos + (sizeof(data[0]) * 2) + sizeof(value)) {
06725       ast_log(LOG_WARNING, "No space left for connected line source\n");
06726       return -1;
06727    }
06728    data[pos++] = AST_CONNECTED_LINE_SOURCE;
06729    data[pos++] = sizeof(value);
06730    value = htonl(connected->source);
06731    memcpy(data + pos, &value, sizeof(value));
06732    pos += sizeof(value);
06733 
06734    /* Connected line Subaddress */
06735    if (connected->id.subaddress.str) {
06736       length = strlen(connected->id.subaddress.str);
06737       if (datalen < pos + (sizeof(data[0]) * 2) + length) {
06738          ast_log(LOG_WARNING, "No space left for connected line subaddress\n");
06739          return -1;
06740       }
06741       data[pos++] = AST_CONNECTED_LINE_SUBADDRESS;
06742       data[pos++] = length;
06743       memcpy(data + pos, connected->id.subaddress.str, length);
06744       pos += length;
06745    }
06746    /* Connected line Subaddress Type */
06747    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
06748       ast_log(LOG_WARNING, "No space left for connected line type of subaddress\n");
06749       return -1;
06750    }
06751    data[pos++] = AST_CONNECTED_LINE_SUBADDRESS_TYPE;
06752    data[pos++] = 1;
06753    data[pos++] = connected->id.subaddress.type;
06754 
06755    /* Connected line Subaddress Odd/Even indicator */
06756    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
06757       ast_log(LOG_WARNING,
06758          "No space left for connected line subaddress odd-even indicator\n");
06759       return -1;
06760    }
06761    data[pos++] = AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN;
06762    data[pos++] = 1;
06763    data[pos++] = connected->id.subaddress.odd_even_indicator;
06764 
06765    /* Connected line Subaddress Valid */
06766    if (datalen < pos + (sizeof(data[0]) * 2) + 1) {
06767       ast_log(LOG_WARNING, "No space left for connected line subaddress valid\n");
06768       return -1;
06769    }
06770    data[pos++] = AST_CONNECTED_LINE_SUBADDRESS_VALID;
06771    data[pos++] = 1;
06772    data[pos++] = connected->id.subaddress.valid;
06773 
06774    return pos;
06775 }

void ast_connected_line_copy_from_caller ( struct ast_party_connected_line dest,
const struct ast_callerid src 
)

Copy the caller information to the connected line information.

Since:
1.6.3
Parameters:
dest Destination connected line information
src Source caller information
Returns:
Nothing
Note:
Assumes locks are already acquired

Definition at line 6559 of file channel.c.

References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_free, ast_party_id_copy(), ast_party_subaddress_copy(), ast_strdup, ast_callerid::cid_ani, ast_callerid::cid_ani2, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_ton, ast_party_connected_line::id, ast_party_id::name, ast_party_id::number, ast_party_id::number_presentation, ast_party_id::number_type, ast_callerid::subaddress, and ast_party_id::subaddress.

Referenced by begin_dial_channel(), builtin_atxfer(), dial_exec_full(), feature_request_and_dial(), local_call(), pickup_do(), ring_entry(), and wait_for_answer().

06560 {
06561 #if 1
06562    /* Must manually fill in struct ast_party_id until struct ast_callerid goes away */
06563    if (dest->id.number) {
06564       ast_free(dest->id.number);
06565    }
06566    dest->id.number = ast_strdup(src->cid_num);
06567 
06568    if (dest->id.name) {
06569       ast_free(dest->id.name);
06570    }
06571    dest->id.name = ast_strdup(src->cid_name);
06572 
06573    dest->id.number_type = src->cid_ton;
06574    dest->id.number_presentation = src->cid_pres;
06575 
06576 
06577    if (dest->ani) {
06578       ast_free(dest->ani);
06579    }
06580    dest->ani = ast_strdup(src->cid_ani);
06581 
06582    dest->ani2 = src->cid_ani2;
06583    ast_party_subaddress_copy(&dest->id.subaddress, &src->subaddress);
06584 
06585 #else
06586 
06587    /* The src parameter type will become a struct ast_party_caller ptr. */
06588    /* This is future code */
06589 
06590    ast_party_id_copy(&dest->id, &src->id);
06591 
06592    if (dest->ani) {
06593       ast_free(dest->ani);
06594    }
06595    dest->ani = ast_strdup(src->ani);
06596 
06597    dest->ani2 = src->ani2;
06598 #endif
06599 }

void ast_connected_line_copy_to_caller ( struct ast_callerid dest,
const struct ast_party_connected_line src 
)

Copy the connected line information to the caller information.

Since:
1.6.3
Parameters:
dest Destination caller information
src Source connected line information
Returns:
Nothing
Note:
Assumes locks are already acquired

Definition at line 6601 of file channel.c.

References ast_party_connected_line::ani, ast_party_connected_line::ani2, ast_free, ast_party_id_copy(), ast_party_subaddress_copy(), ast_strdup, ast_callerid::cid_ani, ast_callerid::cid_ani2, ast_callerid::cid_name, ast_callerid::cid_num, ast_callerid::cid_pres, ast_callerid::cid_ton, ast_party_connected_line::id, ast_party_id::name, ast_party_id::number, ast_party_id::number_presentation, ast_party_id::number_type, ast_party_id::subaddress, and ast_callerid::subaddress.

Referenced by local_call().

06602 {
06603 #if 1
06604    /* Must manually extract from struct ast_party_id until struct ast_callerid goes away */
06605    if (dest->cid_num) {
06606       ast_free(dest->cid_num);
06607    }
06608    dest->cid_num = ast_strdup(src->id.number);
06609 
06610    if (dest->cid_name) {
06611       ast_free(dest->cid_name);
06612    }
06613    dest->cid_name = ast_strdup(src->id.name);
06614 
06615    dest->cid_ton = src->id.number_type;
06616    dest->cid_pres = src->id.number_presentation;
06617 
06618 
06619    if (dest->cid_ani) {
06620       ast_free(dest->cid_ani);
06621    }
06622    dest->cid_ani = ast_strdup(src->ani);
06623 
06624    dest->cid_ani2 = src->ani2;
06625    ast_party_subaddress_copy(&dest->subaddress, &src->id.subaddress);
06626 
06627 #else
06628 
06629    /* The dest parameter type will become a struct ast_party_caller ptr. */
06630    /* This is future code */
06631 
06632    ast_party_id_copy(&dest->id, &src->id);
06633 
06634    if (dest->ani) {
06635       ast_free(dest->ani);
06636    }
06637    dest->ani = ast_strdup(src->ani);
06638 
06639    dest->ani2 = src->ani2;
06640 #endif
06641 }

int ast_connected_line_parse_data ( const unsigned char *  data,
size_t  datalen,
struct ast_party_connected_line connected 
)

Parse connected line indication frame data.

Since:
1.6.3
Parameters:
data Buffer with the frame data to parse
datalen Size of the buffer
connected Extracted connected line information
Return values:
0 on success.
-1 on error.
Note:
The filled in connected line structure needs to be initialized by ast_party_connected_line_set_init() before calling. If defaults are not required use ast_party_connected_line_init().

The filled in connected line structure needs to be destroyed by ast_party_connected_line_free() when it is no longer needed.

Definition at line 6777 of file channel.c.

References AST_CONNECTED_LINE_NAME, AST_CONNECTED_LINE_NUMBER, AST_CONNECTED_LINE_NUMBER_PRESENTATION, AST_CONNECTED_LINE_NUMBER_TYPE, AST_CONNECTED_LINE_SOURCE, AST_CONNECTED_LINE_SUBADDRESS, AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, AST_CONNECTED_LINE_SUBADDRESS_TYPE, AST_CONNECTED_LINE_SUBADDRESS_VALID, ast_free, ast_log(), ast_malloc, ast_party_connected_line::id, LOG_DEBUG, LOG_WARNING, ast_party_id::name, ast_party_id::number, ast_party_id::number_presentation, ast_party_id::number_type, ast_party_subaddress::odd_even_indicator, ast_party_connected_line::source, ast_party_subaddress::str, ast_party_id::subaddress, ast_party_subaddress::type, ast_party_subaddress::valid, and value.

Referenced by ast_channel_connected_line_macro(), ast_indicate_data(), socket_process(), and wait_for_answer().

06778 {
06779    size_t pos;
06780    unsigned char ie_len;
06781    unsigned char ie_id;
06782    int32_t value;
06783 
06784    for (pos = 0; pos < datalen; pos += ie_len) {
06785       if (datalen < pos + sizeof(ie_id) + sizeof(ie_len)) {
06786          ast_log(LOG_WARNING, "Invalid connected line update\n");
06787          return -1;
06788       }
06789       ie_id = data[pos++];
06790       ie_len = data[pos++];
06791       if (datalen < pos + ie_len) {
06792          ast_log(LOG_WARNING, "Invalid connected line update\n");
06793          return -1;
06794       }
06795 
06796       switch (ie_id) {
06797       case AST_CONNECTED_LINE_NUMBER:
06798          if (connected->id.number) {
06799             ast_free(connected->id.number);
06800          }
06801          connected->id.number = ast_malloc(ie_len + 1);
06802          if (connected->id.number) {
06803             memcpy(connected->id.number, data + pos, ie_len);
06804             connected->id.number[ie_len] = 0;
06805          }
06806          break;
06807       case AST_CONNECTED_LINE_NAME:
06808          if (connected->id.name) {
06809             ast_free(connected->id.name);
06810          }
06811          connected->id.name = ast_malloc(ie_len + 1);
06812          if (connected->id.name) {
06813             memcpy(connected->id.name, data + pos, ie_len);
06814             connected->id.name[ie_len] = 0;
06815          }
06816          break;
06817       case AST_CONNECTED_LINE_NUMBER_TYPE:
06818          if (ie_len != 1) {
06819             ast_log(LOG_WARNING, "Invalid connected line type of number (%u)\n", (unsigned) ie_len);
06820             break;
06821          }
06822          connected->id.number_type = data[pos];
06823          break;
06824       case AST_CONNECTED_LINE_NUMBER_PRESENTATION:
06825          if (ie_len != 1) {
06826             ast_log(LOG_WARNING, "Invalid connected line presentation (%u)\n", (unsigned) ie_len);
06827             break;
06828          }
06829          connected->id.number_presentation = data[pos];
06830          break;
06831       case AST_CONNECTED_LINE_SOURCE:
06832          if (ie_len != sizeof(value)) {
06833             ast_log(LOG_WARNING, "Invalid connected line source (%u)\n", (unsigned) ie_len);
06834             break;
06835          }
06836          memcpy(&value, data + pos, sizeof(value));
06837          connected->source = ntohl(value);
06838          break;
06839       case AST_CONNECTED_LINE_SUBADDRESS:
06840          if (connected->id.subaddress.str) {
06841             ast_free(connected->id.subaddress.str);
06842          }
06843          connected->id.subaddress.str = ast_malloc(ie_len + 1);
06844          if (connected->id.subaddress.str) {
06845             memcpy(connected->id.subaddress.str, data + pos, ie_len);
06846             connected->id.subaddress.str[ie_len] = 0;
06847          }
06848          break;
06849       case AST_CONNECTED_LINE_SUBADDRESS_TYPE:
06850          if (ie_len != 1) {
06851             ast_log(LOG_WARNING, "Invalid connected line type of subaddress (%u)\n",
06852                (unsigned) ie_len);
06853             break;
06854          }
06855          connected->id.subaddress.type = data[pos];
06856          break;
06857       case AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN:
06858          if (ie_len != 1) {
06859             ast_log(LOG_WARNING,
06860                "Invalid connected line subaddress odd-even indicator (%u)\n",
06861                (unsigned) ie_len);
06862             break;
06863          }
06864          connected->id.subaddress.odd_even_indicator = data[pos];
06865          break;
06866       case AST_CONNECTED_LINE_SUBADDRESS_VALID:
06867          if (ie_len != 1) {
06868             ast_log(LOG_WARNING, "Invalid connected line subaddress valid (%u)\n",
06869                (unsigned) ie_len);
06870             break;
06871          }
06872          connected->id.subaddress.valid = data[pos];
06873          break;
06874       default:
06875          ast_log(LOG_DEBUG, "Unknown connected line element: %u (%u)\n", (unsigned) ie_id, (unsigned) ie_len);
06876          break;
06877       }
06878    }
06879 
06880    return 0;
06881 }

void ast_deactivate_generator ( struct ast_channel chan  ) 

int ast_do_masquerade ( struct ast_channel original  ) 

Masquerade a channel.

Start masquerading a channel.

Note:
Assumes _NO_ channels and _NO_ channel pvt's are locked. If a channel is locked while calling this function, it invalidates our channel container locking order. All channels must be unlocked before it is permissible to lock the channels' ao2 container.

Definition at line 5100 of file channel.c.

References __ast_change_name_nolink(), ast_channel::_bridge, ast_channel::_softhangup, ast_channel::_state, ast_channel::accountcode, accountcode, ast_channel::adsicpe, ast_channel::alertpipe, ao2_link, ao2_lock(), ao2_unlink, ao2_unlock(), ast_app_group_update(), ast_autochan_new_channel(), ast_cause2str(), AST_CEL_BRIDGE_UPDATE, ast_cel_report_event(), ast_channel_lock, AST_CHANNEL_NAME, ast_channel_release(), ast_channel_set_fd(), ast_channel_set_linkgroup(), ast_channel_trylock, ast_channel_unlock, ast_copy_flags, 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, CHANNEL_DEADLOCK_AVOIDANCE, channels, ast_channel::cid, clone_variables(), ast_channel::connected, ast_datastore::data, ast_channel::datastores, 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, ast_channel::language, language, LOG_WARNING, manager_event, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, ast_channel::musicclass, musicclass, ast_channel::name, ast_channel::nativeformats, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel::readformat, ast_channel::readq, ast_channel::redirecting, report_new_callerid(), S_OR, ast_channel::tech, ast_channel::tech_pvt, ast_channel::timingfd, ast_channel_tech::type, ast_channel::uniqueid, 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(), local_attended_transfer(), sip_park(), and sip_park_thread().

05101 {
05102    int x,i;
05103    int res=0;
05104    int origstate;
05105    struct ast_frame *current;
05106    const struct ast_channel_tech *t;
05107    void *t_pvt;
05108    union {
05109       struct ast_callerid cid;
05110       struct ast_party_connected_line connected;
05111       struct ast_party_redirecting redirecting;
05112    } exchange;
05113    struct ast_channel *clonechan;
05114    struct ast_cdr *cdr;
05115    int rformat = original->readformat;
05116    int wformat = original->writeformat;
05117    char newn[AST_CHANNEL_NAME];
05118    char orig[AST_CHANNEL_NAME];
05119    char masqn[AST_CHANNEL_NAME];
05120    char zombn[AST_CHANNEL_NAME];
05121 
05122    /* XXX This operation is a bit odd.  We're essentially putting the guts of
05123     * the clone channel into the original channel.  Start by killing off the
05124     * original channel's backend.  While the features are nice, which is the
05125     * reason we're keeping it, it's still awesomely weird. XXX */
05126 
05127    /* The reasoning for the channels ao2_container lock here is complex.
05128     * 
05129     * In order to check for a race condition, the original channel must
05130     * be locked.  If it is determined that the masquerade should proceed
05131     * the original channel can absolutely not be unlocked until the end
05132     * of the function.  Since after determining the masquerade should
05133     * continue requires the channels to be unlinked from the ao2_container,
05134     * the container lock must be held first to achieve proper locking order.
05135     */
05136    ao2_lock(channels);
05137 
05138    /* lock the original channel to determine if the masquerade is require or not */
05139    ast_channel_lock(original);
05140 
05141    /* This checks to see if the masquerade has already happened or not.  There is a
05142     * race condition that exists for this function. Since all pvt and channel locks
05143     * must be let go before calling do_masquerade, it is possible that it could be
05144     * called multiple times for the same channel.  This check verifies whether
05145     * or not the masquerade has already been completed by another thread */
05146    if (!original->masq) {
05147       ast_channel_unlock(original);
05148       ao2_unlock(channels);
05149       return 0; /* masq already completed by another thread, or never needed to be done to begin with */
05150    }
05151 
05152    /* now that we have verified no race condition exists, set the clone channel */
05153    clonechan = original->masq;
05154 
05155    /* since this function already holds the global container lock, unlocking original
05156     * for deadlock avoidance will not result in any sort of masquerade race condition.
05157     * If masq is called by a different thread while this happens, it will be stuck waiting
05158     * until we unlock the container. */
05159    while (ast_channel_trylock(clonechan)) {
05160       CHANNEL_DEADLOCK_AVOIDANCE(original);
05161    }
05162 
05163    /* clear the masquerade channels */
05164    original->masq = NULL;
05165    clonechan->masqr = NULL;
05166 
05167    /* unlink from channels container as name (which is the hash value) will change */
05168    ao2_unlink(channels, original);
05169    ao2_unlink(channels, clonechan);
05170 
05171    /* now that both channels are locked and unlinked from the container, it is safe to unlock it */
05172    ao2_unlock(channels);
05173 
05174    ast_debug(4, "Actually Masquerading %s(%d) into the structure of %s(%d)\n",
05175       clonechan->name, clonechan->_state, original->name, original->_state);
05176 
05177    manager_event(EVENT_FLAG_CALL, "Masquerade", "Clone: %s\r\nCloneState: %s\r\nOriginal: %s\r\nOriginalState: %s\r\n",
05178             clonechan->name, ast_state2str(clonechan->_state), original->name, ast_state2str(original->_state));
05179 
05180    /* Having remembered the original read/write formats, we turn off any translation on either
05181       one */
05182    free_translation(clonechan);
05183    free_translation(original);
05184 
05185    /* Save the original name */
05186    ast_copy_string(orig, original->name, sizeof(orig));
05187    /* Save the new name */
05188    ast_copy_string(newn, clonechan->name, sizeof(newn));
05189    /* Create the masq name */
05190    snprintf(masqn, sizeof(masqn), "%s<MASQ>", newn);
05191 
05192    /* Mangle the name of the clone channel */
05193    __ast_change_name_nolink(clonechan, masqn);
05194 
05195    /* Copy the name from the clone channel */
05196    __ast_change_name_nolink(original, newn);
05197 
05198    /* share linked id's */
05199    ast_channel_set_linkgroup(original, clonechan);
05200 
05201    /* Swap the technologies */
05202    t = original->tech;
05203    original->tech = clonechan->tech;
05204    clonechan->tech = t;
05205 
05206    /* Swap the cdrs */
05207    cdr = original->cdr;
05208    original->cdr = clonechan->cdr;
05209    clonechan->cdr = cdr;
05210 
05211    t_pvt = original->tech_pvt;
05212    original->tech_pvt = clonechan->tech_pvt;
05213    clonechan->tech_pvt = t_pvt;
05214 
05215    /* Swap the alertpipes */
05216    for (i = 0; i < 2; i++) {
05217       x = original->alertpipe[i];
05218       original->alertpipe[i] = clonechan->alertpipe[i];
05219       clonechan->alertpipe[i] = x;
05220    }
05221 
05222    /* 
05223     * Swap the readq's.  The end result should be this:
05224     *
05225     *  1) All frames should be on the new (original) channel.
05226     *  2) Any frames that were already on the new channel before this
05227     *     masquerade need to be at the end of the readq, after all of the
05228     *     frames on the old (clone) channel.
05229     *  3) The alertpipe needs to get poked for every frame that was already
05230     *     on the new channel, since we are now using the alert pipe from the
05231     *     old (clone) channel.
05232     */
05233    {
05234       AST_LIST_HEAD_NOLOCK(, ast_frame) tmp_readq;
05235       AST_LIST_HEAD_SET_NOLOCK(&tmp_readq, NULL);
05236 
05237       AST_LIST_APPEND_LIST(&tmp_readq, &original->readq, frame_list);
05238       AST_LIST_APPEND_LIST(&original->readq, &clonechan->readq, frame_list);
05239 
05240       while ((current = AST_LIST_REMOVE_HEAD(&tmp_readq, frame_list))) {
05241          AST_LIST_INSERT_TAIL(&original->readq, current, frame_list);
05242          if (original->alertpipe[1] > -1) {
05243             int poke = 0;
05244 
05245             if (write(original->alertpipe[1], &poke, sizeof(poke)) < 0) {
05246                ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
05247             }
05248          }
05249       }
05250    }
05251 
05252    /* Swap the raw formats */
05253    x = original->rawreadformat;
05254    original->rawreadformat = clonechan->rawreadformat;
05255    clonechan->rawreadformat = x;
05256    x = original->rawwriteformat;
05257    original->rawwriteformat = clonechan->rawwriteformat;
05258    clonechan->rawwriteformat = x;
05259 
05260    clonechan->_softhangup = AST_SOFTHANGUP_DEV;
05261 
05262    /* And of course, so does our current state.  Note we need not
05263       call ast_setstate since the event manager doesn't really consider
05264       these separate.  We do this early so that the clone has the proper
05265       state of the original channel. */
05266    origstate = original->_state;
05267    original->_state = clonechan->_state;
05268    clonechan->_state = origstate;
05269 
05270    if (clonechan->tech->fixup && clonechan->tech->fixup(original, clonechan)) {
05271       ast_log(LOG_WARNING, "Fixup failed on channel %s, strange things may happen.\n", clonechan->name);
05272    }
05273 
05274    /* Start by disconnecting the original's physical side */
05275    if (clonechan->tech->hangup && clonechan->tech->hangup(clonechan)) {
05276       ast_log(LOG_WARNING, "Hangup failed!  Strange things may happen!\n");
05277       res = -1;
05278       goto done;
05279    }
05280 
05281    /* Mangle the name of the clone channel */
05282    snprintf(zombn, sizeof(zombn), "%s<ZOMBIE>", orig); /* quick, hide the brains! */
05283    __ast_change_name_nolink(clonechan, zombn);
05284 
05285    /* Update the type. */
05286    t_pvt = original->monitor;
05287    original->monitor = clonechan->monitor;
05288    clonechan->monitor = t_pvt;
05289 
05290    /* Keep the same language.  */
05291    ast_string_field_set(original, language, clonechan->language);
05292    /* Copy the FD's other than the generator fd */
05293    for (x = 0; x < AST_MAX_FDS; x++) {
05294       if (x != AST_GENERATOR_FD)
05295          ast_channel_set_fd(original, x, clonechan->fds[x]);
05296    }
05297 
05298    ast_app_group_update(clonechan, original);
05299 
05300    /* Move data stores over */
05301    if (AST_LIST_FIRST(&clonechan->datastores)) {
05302       struct ast_datastore *ds;
05303       /* We use a safe traversal here because some fixup routines actually
05304        * remove the datastore from the list and free them.
05305        */
05306       AST_LIST_TRAVERSE_SAFE_BEGIN(&clonechan->datastores, ds, entry) {
05307          if (ds->info->chan_fixup)
05308             ds->info->chan_fixup(ds->data, clonechan, original);
05309       }
05310       AST_LIST_TRAVERSE_SAFE_END;
05311       AST_LIST_APPEND_LIST(&original->datastores, &clonechan->datastores, entry);
05312    }
05313 
05314    ast_autochan_new_channel(clonechan, original);
05315 
05316    clone_variables(original, clonechan);
05317    /* Presense of ADSI capable CPE follows clone */
05318    original->adsicpe = clonechan->adsicpe;
05319    /* Bridge remains the same */
05320    /* CDR fields remain the same */
05321    /* XXX What about blocking, softhangup, blocker, and lock and blockproc? XXX */
05322    /* Application and data remain the same */
05323    /* Clone exception  becomes real one, as with fdno */
05324    ast_copy_flags(original, clonechan, AST_FLAG_EXCEPTION | AST_FLAG_OUTGOING);
05325    original->fdno = clonechan->fdno;
05326    /* Schedule context remains the same */
05327    /* Stream stuff stays the same */
05328    /* Keep the original state.  The fixup code will need to work with it most likely */
05329 
05330    /*
05331     * Just swap the whole structures, nevermind the allocations,
05332     * they'll work themselves out.
05333     */
05334    exchange.cid = original->cid;
05335    original->cid = clonechan->cid;
05336    clonechan->cid = exchange.cid;
05337    report_new_callerid(original);
05338 
05339    exchange.connected = original->connected;
05340    original->connected = clonechan->connected;
05341    clonechan->connected = exchange.connected;
05342    exchange.redirecting = original->redirecting;
05343    original->redirecting = clonechan->redirecting;
05344    clonechan->redirecting = exchange.redirecting;
05345 
05346    /* Restore original timing file descriptor */
05347    ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd);
05348 
05349    /* Our native formats are different now */
05350    original->nativeformats = clonechan->nativeformats;
05351 
05352    /* Context, extension, priority, app data, jump table,  remain the same */
05353    /* pvt switches.  pbx stays the same, as does next */
05354 
05355    /* Set the write format */
05356    ast_set_write_format(original, wformat);
05357 
05358    /* Set the read format */
05359    ast_set_read_format(original, rformat);
05360 
05361    /* Copy the music class */
05362    ast_string_field_set(original, musicclass, clonechan->musicclass);
05363 
05364    /* copy over accuntcode and set peeraccount across the bridge */
05365    ast_string_field_set(original, accountcode, S_OR(clonechan->accountcode, ""));
05366    if (original->_bridge) {
05367       /* XXX - should we try to lock original->_bridge here? */
05368       ast_string_field_set(original->_bridge, peeraccount, S_OR(clonechan->accountcode, ""));
05369       ast_cel_report_event(original, AST_CEL_BRIDGE_UPDATE, NULL, NULL, NULL);
05370    }
05371 
05372    ast_debug(1, "Putting channel %s in %d/%d formats\n", original->name, wformat, rformat);
05373 
05374    /* Okay.  Last thing is to let the channel driver know about all this mess, so he
05375       can fix up everything as best as possible */
05376    if (original->tech->fixup) {
05377       if (original->tech->fixup(clonechan, original)) {
05378          ast_log(LOG_WARNING, "Channel for type '%s' could not fixup channel %s\n",
05379             original->tech->type, original->name);
05380          res = -1;
05381          goto done;
05382       }
05383    } else
05384       ast_log(LOG_WARNING, "Channel type '%s' does not have a fixup routine (for %s)!  Bad things may happen.\n",
05385          original->tech->type, original->name);
05386 
05387    /* 
05388     * If an indication is currently playing, maintain it on the channel 
05389     * that is taking the place of original 
05390     *
05391     * This is needed because the masquerade is swapping out in the internals
05392     * of this channel, and the new channel private data needs to be made
05393     * aware of the current visible indication (RINGING, CONGESTION, etc.)
05394     */
05395    if (original->visible_indication) {
05396       ast_indicate(original, original->visible_indication);
05397    }
05398 
05399    /* Now, at this point, the "clone" channel is totally F'd up.  We mark it as
05400       a zombie so nothing tries to touch it.  If it's already been marked as a
05401       zombie, then free it now (since it already is considered invalid). */
05402    if (ast_test_flag(clonechan, AST_FLAG_ZOMBIE)) {
05403       ast_debug(1, "Destroying channel clone '%s'\n", clonechan->name);
05404       ast_channel_unlock(clonechan);
05405       manager_event(EVENT_FLAG_CALL, "Hangup",
05406          "Channel: %s\r\n"
05407          "Uniqueid: %s\r\n"
05408          "Cause: %d\r\n"
05409          "Cause-txt: %s\r\n",
05410          clonechan->name,
05411          clonechan->uniqueid,
05412          clonechan->hangupcause,
05413          ast_cause2str(clonechan->hangupcause)
05414          );
05415       clonechan = ast_channel_release(clonechan);
05416    } else {
05417       ast_debug(1, "Released clone lock on '%s'\n", clonechan->name);
05418       ast_set_flag(clonechan, AST_FLAG_ZOMBIE);
05419       ast_queue_frame(clonechan, &ast_null_frame);
05420    }
05421 
05422    /* Signal any blocker */
05423    if (ast_test_flag(original, AST_FLAG_BLOCKING))
05424       pthread_kill(original->blocker, SIGURG);
05425    ast_debug(1, "Done Masquerading %s (%d)\n", original->name, original->_state);
05426 
05427 done:
05428    /* it is possible for the clone channel to disappear during this */
05429    if (clonechan) {
05430       ast_channel_unlock(original);
05431       ast_channel_unlock(clonechan);
05432       ao2_link(channels, clonechan);
05433       ao2_link(channels, original);
05434    } else {
05435       ast_channel_unlock(original);
05436       ao2_link(channels, original);
05437    }
05438    return 0;
05439 }

struct ast_channel* ast_dummy_channel_alloc ( void   )  [read]

Create a fake channel structure.

Return values:
NULL failure
non-NULL successfully allocated channel
Note:
This function should ONLY be used to create a fake channel that can then be populated with data for use in variable substitution when a real channel does not exist.

Definition at line 1027 of file channel.c.

References __ao2_alloc_debug(), ao2_alloc, ast_channel_unref, ast_dummy_channel_destructor(), AST_LIST_HEAD_INIT_NOLOCK, ast_string_field_init, and ast_channel::varshead.

Referenced by acf_odbc_read(), acf_odbc_write(), action_getvar(), ast_add_extension2_lockopt(), ast_cel_fabricate_channel_from_event(), ast_pbx_outgoing_cdr_failed(), ast_str_substitute_variables_full(), cli_odbc_read(), cli_odbc_write(), custom_log(), make_email_file(), manager_log(), pbx_substitute_variables_helper_full(), rotate_file(), sendmail(), sendpage(), sqlite3_log(), and syslog_log().

01029 {
01030    struct ast_channel *tmp;
01031    struct varshead *headp;
01032 
01033 #if defined(REF_DEBUG)
01034    if (!(tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", file, line, function, 1))) {
01035       return NULL;
01036    }
01037 #elif defined(__AST_DEBUG_MALLOC)
01038    if (!(tmp = __ao2_alloc_debug(sizeof(*tmp), ast_dummy_channel_destructor, "dummy channel", file, line, function, 0))) {
01039       return NULL;
01040    }
01041 #else
01042    if (!(tmp = ao2_alloc(sizeof(*tmp), ast_dummy_channel_destructor))) {
01043       return NULL;
01044    }
01045 #endif
01046 
01047    if ((ast_string_field_init(tmp, 128))) {
01048       ast_channel_unref(tmp);
01049       return NULL;
01050    }
01051 
01052    headp = &tmp->varshead;
01053    AST_LIST_HEAD_INIT_NOLOCK(headp);
01054 
01055    return tmp;
01056 }

static void ast_dummy_channel_destructor ( void *  obj  )  [static]

Free a dummy channel structure.

Definition at line 1919 of file channel.c.

References ast_cdr_discard(), AST_LIST_REMOVE_HEAD, ast_string_field_free_memory, ast_var_delete(), ast_channel::cdr, ast_channel::cid, free_cid(), and ast_channel::varshead.

Referenced by ast_dummy_channel_alloc().

01920 {
01921    struct ast_channel *chan = obj;
01922    struct ast_var_t *vardata;
01923    struct varshead *headp;
01924 
01925    headp = &chan->varshead;
01926 
01927    free_cid(&chan->cid);
01928 
01929    /* loop over the variables list, freeing all data and deleting list items */
01930    /* no need to lock the list, as the channel is already locked */
01931    while ((vardata = AST_LIST_REMOVE_HEAD(headp, entries)))
01932       ast_var_delete(vardata);
01933 
01934    if (chan->cdr) {
01935       ast_cdr_discard(chan->cdr);
01936       chan->cdr = NULL;
01937    }
01938 
01939    ast_string_field_free_memory(chan);
01940 }

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 
) [static]

Definition at line 5547 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_channel_connected_line_macro(), ast_clear_flag, AST_CONTROL_CONNECTED_LINE, AST_CONTROL_HOLD, AST_CONTROL_REDIRECTING, AST_CONTROL_SRCUPDATE, 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_test_flag, 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::name, ast_channel::nativeformats, ast_bridge_config::nexteventts, ast_frame::ptr, ast_frame::subclass, ast_channel::tech_pvt, and ast_bridge_config::timelimit.

Referenced by ast_channel_bridge().

05550 {
05551    /* Copy voice back and forth between the two channels. */
05552    struct ast_channel *cs[3];
05553    struct ast_frame *f;
05554    enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
05555    int o0nativeformats;
05556    int o1nativeformats;
05557    int watch_c0_dtmf;
05558    int watch_c1_dtmf;
05559    void *pvt0, *pvt1;
05560    /* Indicates whether a frame was queued into a jitterbuffer */
05561    int frame_put_in_jb = 0;
05562    int jb_in_use;
05563    int to;
05564    
05565    cs[0] = c0;
05566    cs[1] = c1;
05567    pvt0 = c0->tech_pvt;
05568    pvt1 = c1->tech_pvt;
05569    o0nativeformats = c0->nativeformats;
05570    o1nativeformats = c1->nativeformats;
05571    watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
05572    watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
05573 
05574    /* Check the need of a jitterbuffer for each channel */
05575    jb_in_use = ast_jb_do_usecheck(c0, c1);
05576    if (jb_in_use)
05577       ast_jb_empty_and_reset(c0, c1);
05578 
05579    ast_poll_channel_add(c0, c1);
05580 
05581    if (config->feature_timer > 0 && ast_tvzero(config->nexteventts)) {
05582       /* nexteventts is not set when the bridge is not scheduled to
05583        * break, so calculate when the bridge should possibly break
05584        * if a partial feature match timed out */
05585       config->nexteventts = ast_tvadd(ast_tvnow(), ast_samp2tv(config->feature_timer, 1000));
05586    }
05587 
05588    for (;;) {
05589       struct ast_channel *who, *other;
05590 
05591       if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
05592           (o0nativeformats != c0->nativeformats) ||
05593           (o1nativeformats != c1->nativeformats)) {
05594          /* Check for Masquerade, codec changes, etc */
05595          res = AST_BRIDGE_RETRY;
05596          break;
05597       }
05598       if (config->nexteventts.tv_sec) {
05599          to = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
05600          if (to <= 0) {
05601             if (config->timelimit && !config->feature_timer && !ast_test_flag(config, AST_FEATURE_WARNING_ACTIVE)) {
05602                res = AST_BRIDGE_RETRY;
05603                /* generic bridge ending to play warning */
05604                ast_set_flag(config, AST_FEATURE_WARNING_ACTIVE);
05605             } else if (config->feature_timer) {
05606                /* feature timer expired - make sure we do not play warning */
05607                ast_clear_flag(config, AST_FEATURE_WARNING_ACTIVE);
05608                res = AST_BRIDGE_RETRY;
05609             } else {
05610                res = AST_BRIDGE_COMPLETE;
05611             }
05612             break;
05613          }
05614       } else {
05615          /* If a feature has been started and the bridge is configured to 
05616           * to not break, leave the channel bridge when the feature timer
05617           * time has elapsed so the DTMF will be sent to the other side. 
05618           */
05619          if (!ast_tvzero(config->nexteventts)) {
05620             int diff = ast_tvdiff_ms(config->nexteventts, ast_tvnow());
05621             if (diff <= 0) {
05622                res = AST_BRIDGE_RETRY;
05623                break;
05624             }
05625          }
05626          to = -1;
05627       }
05628       /* Calculate the appropriate max sleep interval - in general, this is the time,
05629          left to the closest jb delivery moment */
05630       if (jb_in_use)
05631          to = ast_jb_get_when_to_wakeup(c0, c1, to);
05632       who = ast_waitfor_n(cs, 2, &to);
05633       if (!who) {
05634          /* No frame received within the specified timeout - check if we have to deliver now */
05635          if (jb_in_use)
05636             ast_jb_get_and_deliver(c0, c1);
05637          if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE || c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE) {
05638             if (c0->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
05639                c0->_softhangup = 0;
05640             if (c1->_softhangup == AST_SOFTHANGUP_UNBRIDGE)
05641                c1->_softhangup = 0;
05642             c0->_bridge = c1;
05643             c1->_bridge = c0;
05644          }
05645          continue;
05646       }
05647       f = ast_read(who);
05648       if (!f) {
05649          *fo = NULL;
05650          *rc = who;
05651          ast_debug(1, "Didn't get a frame from channel: %s\n",who->name);
05652          break;
05653       }
05654 
05655       other = (who == c0) ? c1 : c0; /* the 'other' channel */
05656       /* Try add the frame info the who's bridged channel jitterbuff */
05657       if (jb_in_use)
05658          frame_put_in_jb = !ast_jb_put(other, f);
05659 
05660       if ((f->frametype == AST_FRAME_CONTROL) && !(config->flags & AST_BRIDGE_IGNORE_SIGS)) {
05661          int bridge_exit = 0;
05662 
05663          switch (f->subclass) {
05664          case AST_CONTROL_REDIRECTING:
05665             ast_indicate_data(other, f->subclass, f->data.ptr, f->datalen);
05666             break;
05667          case AST_CONTROL_CONNECTED_LINE:
05668             if (ast_channel_connected_line_macro(who, other, f, other == c0, 1)) {
05669                ast_indicate_data(other, f->subclass, f->data.ptr, f->datalen);
05670             }
05671             break;
05672          case AST_CONTROL_HOLD:
05673          case AST_CONTROL_UNHOLD:
05674          case AST_CONTROL_VIDUPDATE:
05675          case AST_CONTROL_SRCUPDATE:
05676             ast_indicate_data(other, f->subclass, f->data.ptr, f->datalen);
05677             if (jb_in_use) {
05678                ast_jb_empty_and_reset(c0, c1);
05679             }
05680             break;
05681          default:
05682             *fo = f;
05683             *rc = who;
05684             bridge_exit = 1;
05685             ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name);
05686             break;
05687          }
05688          if (bridge_exit)
05689             break;
05690       }
05691       if ((f->frametype == AST_FRAME_VOICE) ||
05692           (f->frametype == AST_FRAME_DTMF_BEGIN) ||
05693           (f->frametype == AST_FRAME_DTMF) ||
05694           (f->frametype == AST_FRAME_VIDEO) ||
05695           (f->frametype == AST_FRAME_IMAGE) ||
05696           (f->frametype == AST_FRAME_HTML) ||
05697           (f->frametype == AST_FRAME_MODEM) ||
05698           (f->frametype == AST_FRAME_TEXT)) {
05699          /* monitored dtmf causes exit from bridge */
05700          int monitored_source = (who == c0) ? watch_c0_dtmf : watch_c1_dtmf;
05701 
05702          if (monitored_source &&
05703             (f->frametype == AST_FRAME_DTMF_END ||
05704             f->frametype == AST_FRAME_DTMF_BEGIN)) {
05705             *fo = f;
05706             *rc = who;
05707             ast_debug(1, "Got DTMF %s on channel (%s)\n", 
05708                f->frametype == AST_FRAME_DTMF_END ? "end" : "begin",
05709                who->name);
05710 
05711             break;
05712          }
05713          /* Write immediately frames, not passed through jb */
05714          if (!frame_put_in_jb)
05715             ast_write(other, f);
05716             
05717          /* Check if we have to deliver now */
05718          if (jb_in_use)
05719             ast_jb_get_and_deliver(c0, c1);
05720       }
05721       /* XXX do we want to pass on also frames not matched above ? */
05722       ast_frfree(f);
05723 
05724 #ifndef HAVE_EPOLL
05725       /* Swap who gets priority */
05726       cs[2] = cs[0];
05727       cs[0] = cs[1];
05728       cs[1] = cs[2];
05729 #endif
05730    }
05731 
05732    ast_poll_channel_del(c0, c1);
05733 
05734    return res;
05735 }

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

References AST_RWLIST_RDLOCK, AST_RWLIST_TRAVERSE, AST_RWLIST_UNLOCK, chanlist::tech, and ast_channel_tech::type.

Referenced by _ast_device_state(), and ast_var_channel_types_table().

00621 {
00622    struct chanlist *chanls;
00623    const struct ast_channel_tech *ret = NULL;
00624 
00625    AST_RWLIST_RDLOCK(&backends);
00626 
00627    AST_RWLIST_TRAVERSE(&backends, chanls, list) {
00628       if (!strcasecmp(name, chanls->tech->type)) {
00629          ret = chanls->tech;
00630          break;
00631       }
00632    }
00633 
00634    AST_RWLIST_UNLOCK(&backends);
00635    
00636    return ret;
00637 }

ast_group_t ast_get_group ( const char *  s  ) 

Definition at line 6277 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(), config_parse_variables(), func_channel_write(), process_dahdi(), and read_agent_config().

06278 {
06279    char *piece;
06280    char *c;
06281    int start=0, finish=0, x;
06282    ast_group_t group = 0;
06283 
06284    if (ast_strlen_zero(s))
06285       return 0;
06286 
06287    c = ast_strdupa(s);
06288    
06289    while ((piece = strsep(&c, ","))) {
06290       if (sscanf(piece, "%30d-%30d", &start, &finish) == 2) {
06291          /* Range */
06292       } else if (sscanf(piece, "%30d", &start)) {
06293          /* Just one */
06294          finish = start;
06295       } else {
06296          ast_log(LOG_ERROR, "Syntax error parsing group configuration '%s' at '%s'. Ignoring.\n", s, piece);
06297          continue;
06298       }
06299       for (x = start; x <= finish; x++) {
06300          if ((x > 63) || (x < 0)) {
06301             ast_log(LOG_WARNING, "Ignoring invalid group %d (maximum group is 63)\n", x);
06302          } else
06303             group |= ((ast_group_t) 1 << x);
06304       }
06305    }
06306    return group;
06307 }

int ast_hangup ( struct ast_channel chan  ) 

Hangup a channel.

Hang up a channel.

Definition at line 2143 of file channel.c.

References ao2_unlink, 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_CEL_HANGUP, ast_cel_report_event(), ast_channel_lock, ast_channel_release(), ast_channel_unlock, ast_closestream(), ast_debug, ast_do_masquerade(), AST_FLAG_BLOCKING, AST_FLAG_ZOMBIE, ast_log(), ast_set_flag, ast_test_flag, ast_channel::audiohooks, ast_channel::blocker, ast_channel::blockproc, ast_channel::cdr, 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, ast_channel::hangupsource, LOG_WARNING, manager_event, ast_channel::masq, ast_channel::masqr, ast_channel::name, pbx_builtin_getvar_helper(), ast_generator::release, S_OR, ast_channel::sched, sched_context_destroy(), ast_channel::stream, ast_channel::tech, ast_channel::uniqueid, and ast_channel::vstream.

Referenced by __analog_handle_event(), __analog_ss_thread(), __ast_pbx_run(), __ast_request_and_dial(), __oh323_new(), action_bridge(), alsa_new(), analog_handle_init_event(), analog_ss_thread(), answer_exec_run(), app_exec(), ast_async_goto(), ast_call_forward(), ast_dial_destroy(), ast_dial_hangup(), ast_iax2_new(), ast_pbx_outgoing_app(), ast_pbx_outgoing_exten(), ast_pbx_run_app(), async_wait(), begin_dial_channel(), bridge_call_thread(), bridge_channel_thread(), 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(), destroy_conference_bridge(), dial_exec_full(), dial_transfer(), do_forward(), do_hang(), feature_attended_transfer(), feature_request_and_dial(), 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(), my_distinctive_ring(), my_handle_notify_message(), nbs_new(), oss_new(), park_exec_full(), parkandannounce_exec(), phone_new(), play_sound_file(), rpt(), rpt_call(), rpt_exec(), rpt_tele_thread(), sip_new(), sip_park(), sip_park_thread(), skinny_new(), skinny_ss(), try_calling(), unistim_new(), usbradio_new(), wait_for_answer(), and wait_for_winner().

02144 {
02145    int res = 0;
02146    struct ast_cdr *cdr = NULL;
02147    char extra_str[64]; /* used for cel logging below */
02148 
02149    /* Don't actually hang up a channel that will masquerade as someone else, or
02150       if someone is going to masquerade as us */
02151    ast_channel_lock(chan);
02152 
02153    if (chan->audiohooks) {
02154       ast_audiohook_detach_list(chan->audiohooks);
02155       chan->audiohooks = NULL;
02156    }
02157 
02158    ast_autoservice_stop(chan);
02159 
02160    if (chan->masq) {
02161       ast_channel_unlock(chan);
02162       if (ast_do_masquerade(chan)) {
02163          ast_log(LOG_WARNING, "Failed to perform masquerade\n");
02164       }
02165       ast_channel_lock(chan);
02166    }
02167 
02168    if (chan->masq) {
02169       ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
02170       ast_channel_unlock(chan);
02171       return 0;
02172    }
02173    /* If this channel is one which will be masqueraded into something,
02174       mark it as a zombie already, so we know to free it later */
02175    if (chan->masqr) {
02176       ast_set_flag(chan, AST_FLAG_ZOMBIE);
02177       ast_channel_unlock(chan);
02178       return 0;
02179    }
02180    ast_channel_unlock(chan);
02181 
02182    ao2_unlink(channels, chan);
02183 
02184    ast_channel_lock(chan);
02185    free_translation(chan);
02186    /* Close audio stream */
02187    if (chan->stream) {
02188       ast_closestream(chan->stream);
02189       chan->stream = NULL;
02190    }
02191    /* Close video stream */
02192    if (chan->vstream) {
02193       ast_closestream(chan->vstream);
02194       chan->vstream = NULL;
02195    }
02196    if (chan->sched) {
02197       sched_context_destroy(chan->sched);
02198       chan->sched = NULL;
02199    }
02200 
02201    if (chan->generatordata)   /* Clear any tone stuff remaining */
02202       if (chan->generator && chan->generator->release)
02203          chan->generator->release(chan, chan->generatordata);
02204    chan->generatordata = NULL;
02205    chan->generator = NULL;
02206 
02207    snprintf(extra_str, sizeof(extra_str), "%d,%s,%s", chan->hangupcause, chan->hangupsource, S_OR(pbx_builtin_getvar_helper(chan, "DIALSTATUS"), ""));
02208    ast_cel_report_event(chan, AST_CEL_HANGUP, NULL, extra_str, NULL);
02209 
02210    if (chan->cdr) {     /* End the CDR if it hasn't already */
02211       ast_cdr_end(chan->cdr);
02212       cdr = chan->cdr;
02213       chan->cdr = NULL;
02214    }
02215    if (ast_test_flag(chan, AST_FLAG_BLOCKING)) {
02216       ast_log(LOG_WARNING, "Hard hangup called by thread %ld on %s, while fd "
02217                "is blocked by thread %ld in procedure %s!  Expect a failure\n",
02218                (long)pthread_self(), chan->name, (long)chan->blocker, chan->blockproc);
02219       ast_assert(ast_test_flag(chan, AST_FLAG_BLOCKING) == 0);
02220    }
02221    if (!ast_test_flag(chan, AST_FLAG_ZOMBIE)) {
02222       ast_debug(1, "Hanging up channel '%s'\n", chan->name);
02223       if (chan->tech->hangup)
02224          res = chan->tech->hangup(chan);
02225    } else {
02226       ast_debug(1, "Hanging up zombie '%s'\n", chan->name);
02227    }
02228          
02229    ast_channel_unlock(chan);
02230    manager_event(EVENT_FLAG_CALL, "Hangup",
02231          "Channel: %s\r\n"
02232          "Uniqueid: %s\r\n"
02233          "CallerIDNum: %s\r\n"
02234          "CallerIDName: %s\r\n"
02235          "Cause: %d\r\n"
02236          "Cause-txt: %s\r\n",
02237          chan->name,
02238          chan->uniqueid,
02239          S_OR(chan->cid.cid_num, "<unknown>"),
02240          S_OR(chan->cid.cid_name, "<unknown>"),
02241          chan->hangupcause,
02242          ast_cause2str(chan->hangupcause)
02243          );
02244 
02245    if (chan->cdr && !ast_test_flag(chan->cdr, AST_CDR_FLAG_BRIDGED) && 
02246       !ast_test_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED) && 
02247        (chan->cdr->disposition != AST_CDR_NULL || ast_test_flag(chan->cdr, AST_CDR_FLAG_DIALED))) {
02248       ast_channel_lock(chan);
02249          
02250       ast_cdr_end(chan->cdr);
02251       ast_cdr_detach(chan->cdr);
02252       chan->cdr = NULL;
02253       ast_channel_unlock(chan);
02254    }
02255 
02256    chan = ast_channel_release(chan);
02257 
02258    return res;
02259 }

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

References ast_channel::_state, _XXX_AST_CONTROL_T38, ast_channel_lock, ast_channel_set_connected_line(), ast_channel_set_redirecting(), ast_channel_unlock, ast_check_hangup(), ast_connected_line_parse_data(), AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_CONNECTED_LINE, 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_REDIRECTING, AST_CONTROL_RING, AST_CONTROL_RINGING, AST_CONTROL_SRCUPDATE, AST_CONTROL_T38_PARAMETERS, AST_CONTROL_TAKEOFFHOOK, AST_CONTROL_TRANSFER, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_CONTROL_WINK, ast_debug, AST_FLAG_ZOMBIE, ast_get_indication_tone(), ast_log(), ast_party_connected_line_free(), ast_party_connected_line_set_init(), ast_party_redirecting_free(), ast_party_redirecting_set_init(), ast_playtones_start(), ast_playtones_stop(), ast_redirecting_parse_data(), AST_STATE_UP, ast_test_flag, ast_tone_zone_sound_unref(), ast_channel::connected, ast_tone_zone_sound::data, ast_channel_tech::indicate, is_visible_indication(), LOG_WARNING, ast_channel::name, ast_channel::redirecting, ast_channel::tech, ast_channel::visible_indication, and ast_channel::zone.

Referenced by agent_hangup(), ast_bridge_call(), ast_channel_update_connected_line(), ast_channel_update_redirecting(), ast_generic_bridge(), ast_indicate(), feature_request_and_dial(), handle_frame(), local_bridge_loop(), login_exec(), manage_parkinglot(), park_call_full(), pbx_builtin_waitexten(), remote_bridge_loop(), transmit_audio(), transmit_t38(), and wait_for_answer().

03596 {
03597    /* By using an enum, we'll get compiler warnings for values not handled 
03598     * in switch statements. */
03599    enum ast_control_frame_type condition = _condition;
03600    struct ast_tone_zone_sound *ts = NULL;
03601    int res;
03602 
03603    ast_channel_lock(chan);
03604 
03605    /* Don't bother if the channel is about to go away, anyway. */
03606    if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
03607       ast_channel_unlock(chan);
03608       return -1;
03609    }
03610    switch (condition) {
03611    case AST_CONTROL_CONNECTED_LINE:
03612       {
03613          struct ast_party_connected_line connected;
03614 
03615          ast_party_connected_line_set_init(&connected, &chan->connected);
03616          res = ast_connected_line_parse_data(data, datalen, &connected);
03617          if (!res) {
03618             ast_channel_set_connected_line(chan, &connected);
03619          }
03620          ast_party_connected_line_free(&connected);
03621       }
03622       break;
03623 
03624    case AST_CONTROL_REDIRECTING:
03625       {
03626          struct ast_party_redirecting redirecting;
03627 
03628          ast_party_redirecting_set_init(&redirecting, &chan->redirecting);
03629          res = ast_redirecting_parse_data(data, datalen, &redirecting);
03630          if (!res) {
03631             ast_channel_set_redirecting(chan, &redirecting);
03632          }
03633          ast_party_redirecting_free(&redirecting);
03634       }
03635       break;
03636    
03637    default:
03638       break;
03639    }
03640 
03641    if (chan->tech->indicate) {
03642       /* See if the channel driver can handle this condition. */
03643       res = chan->tech->indicate(chan, condition, data, datalen);
03644    } else {
03645       res = -1;
03646    }
03647 
03648    ast_channel_unlock(chan);
03649 
03650    if (!res) {
03651       /* The channel driver successfully handled this indication */
03652       if (is_visible_indication(condition)) {
03653          chan->visible_indication = condition;
03654       }
03655       return 0;
03656    }
03657 
03658    /* The channel driver does not support this indication, let's fake
03659     * it by doing our own tone generation if applicable. */
03660 
03661    /*!\note If we compare the enumeration type, which does not have any
03662     * negative constants, the compiler may optimize this code away.
03663     * Therefore, we must perform an integer comparison here. */
03664    if (_condition < 0) {
03665       /* Stop any tones that are playing */
03666       ast_playtones_stop(chan);
03667       return 0;
03668    }
03669 
03670    /* Handle conditions that we have tones for. */
03671    switch (condition) {
03672    case _XXX_AST_CONTROL_T38:
03673       /* deprecated T.38 control frame */
03674       return -1;
03675    case AST_CONTROL_T38_PARAMETERS:
03676       /* there is no way to provide 'default' behavior for these
03677        * control frames, so we need to return failure, but there
03678        * is also no value in the log message below being emitted
03679        * since failure to handle these frames is not an 'error'
03680        * so just return right now.
03681        */
03682       return -1;
03683    case AST_CONTROL_RINGING:
03684       ts = ast_get_indication_tone(chan->zone, "ring");
03685       /* It is common practice for channel drivers to return -1 if trying
03686        * to indicate ringing on a channel which is up. The idea is to let the
03687        * core generate the ringing inband. However, we don't want the
03688        * warning message about not being able to handle the specific indication
03689        * to print nor do we want ast_indicate_data to return an "error" for this
03690        * condition
03691        */
03692       if (chan->_state == AST_STATE_UP) {
03693          res = 0;
03694       }
03695       break;
03696    case AST_CONTROL_BUSY:
03697       ts = ast_get_indication_tone(chan->zone, "busy");
03698       break;
03699    case AST_CONTROL_CONGESTION:
03700       ts = ast_get_indication_tone(chan->zone, "congestion");
03701       break;
03702    case AST_CONTROL_PROGRESS:
03703    case AST_CONTROL_PROCEEDING:
03704    case AST_CONTROL_VIDUPDATE:
03705    case AST_CONTROL_SRCUPDATE:
03706    case AST_CONTROL_RADIO_KEY:
03707    case AST_CONTROL_RADIO_UNKEY:
03708    case AST_CONTROL_OPTION:
03709    case AST_CONTROL_WINK:
03710    case AST_CONTROL_FLASH:
03711    case AST_CONTROL_OFFHOOK:
03712    case AST_CONTROL_TAKEOFFHOOK:
03713    case AST_CONTROL_ANSWER:
03714    case AST_CONTROL_HANGUP:
03715    case AST_CONTROL_RING:
03716    case AST_CONTROL_HOLD:
03717    case AST_CONTROL_UNHOLD:
03718    case AST_CONTROL_TRANSFER:
03719    case AST_CONTROL_CONNECTED_LINE:
03720    case AST_CONTROL_REDIRECTING:
03721       /* Nothing left to do for these. */
03722       res = 0;
03723       break;
03724    }
03725 
03726    if (ts) {
03727       /* We have a tone to play, yay. */
03728       ast_debug(1, "Driver for channel '%s' does not support indication %d, emulating it\n", chan->name, condition);
03729       ast_playtones_start(chan, 0, ts->data, 1);
03730       ts = ast_tone_zone_sound_unref(ts);
03731       res = 0;
03732       chan->visible_indication = condition;
03733    }
03734 
03735    if (res) {
03736       /* not handled */
03737       ast_log(LOG_WARNING, "Unable to handle indication %d for '%s'\n", condition, chan->name);
03738    }
03739 
03740    return res;
03741 }

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

References ast_moh_cleanup_ptr, ast_moh_start_ptr, and ast_moh_stop_ptr.

Referenced by load_module().

06316 {
06317    ast_moh_start_ptr = start_ptr;
06318    ast_moh_stop_ptr = stop_ptr;
06319    ast_moh_cleanup_ptr = cleanup_ptr;
06320 }

<