#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"

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_channel * | ast_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_channel * | ast_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_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,...) |
| 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_channel * | ast_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_datastore * | ast_channel_datastore_alloc (const struct ast_datastore_info *info, const char *uid) |
| Create a channel data store object. | |
| struct ast_datastore * | ast_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_channel * | ast_channel_get_by_exten (const char *exten, const char *context) |
| Find a channel by extension and context. | |
| struct ast_channel * | ast_channel_get_by_name (const char *name) |
| Find a channel by name. | |
| struct ast_channel * | ast_channel_get_by_name_prefix (const char *name, size_t name_len) |
| Find a channel by a name prefix. | |
| static struct ast_channel * | ast_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_iterator * | ast_channel_iterator_all_new (void) |
| Create a new channel iterator. | |
| struct ast_channel_iterator * | ast_channel_iterator_by_exten_new (const char *exten, const char *context) |
| Create a new channel iterator based on extension. | |
| struct ast_channel_iterator * | ast_channel_iterator_by_name_new (const char *name, size_t name_len) |
| Create a new channel iterator based on name. | |
| struct ast_channel_iterator * | ast_channel_iterator_destroy (struct ast_channel_iterator *i) |
| Destroy a channel iterator. | |
| struct ast_channel * | ast_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_channel * | ast_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_generator * | ast_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_variable * | ast_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_channel * | ast_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_tech * | ast_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_frame * | ast_read (struct ast_channel *chan) |
| Reads a frame. | |
| static void | ast_read_generator_actions (struct ast_channel *chan, struct ast_frame *f) |
| struct ast_frame * | ast_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_channel * | ast_request (const char *type, int format, const struct ast_channel *requestor, void *data, int *cause) |
| Requests a channel. | |
| 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 *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_channel * | ast_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_channel * | ast_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_container * | channels |
| 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 |
Definition in file channel.c.
| #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 |
| #define STATE2STR_BUFSIZE 32 |
| anonymous enum |
Element identifiers for connected line indication frame data.
Definition at line 6659 of file channel.c.
06659 { 06660 AST_CONNECTED_LINE_NUMBER, 06661 AST_CONNECTED_LINE_NAME, 06662 AST_CONNECTED_LINE_NUMBER_TYPE, 06663 AST_CONNECTED_LINE_NUMBER_PRESENTATION, 06664 AST_CONNECTED_LINE_SOURCE, 06665 AST_CONNECTED_LINE_SUBADDRESS, 06666 AST_CONNECTED_LINE_SUBADDRESS_TYPE, 06667 AST_CONNECTED_LINE_SUBADDRESS_ODD_EVEN, 06668 AST_CONNECTED_LINE_SUBADDRESS_VALID 06669 };
| anonymous enum |
Element identifiers for redirecting indication frame data.
Definition at line 6942 of file channel.c.
06942 { 06943 AST_REDIRECTING_FROM_NUMBER, 06944 AST_REDIRECTING_FROM_NAME, 06945 AST_REDIRECTING_FROM_NUMBER_TYPE, 06946 AST_REDIRECTING_FROM_NUMBER_PRESENTATION, 06947 AST_REDIRECTING_TO_NUMBER, 06948 AST_REDIRECTING_TO_NAME, 06949 AST_REDIRECTING_TO_NUMBER_TYPE, 06950 AST_REDIRECTING_TO_NUMBER_PRESENTATION, 06951 AST_REDIRECTING_REASON, 06952 AST_REDIRECTING_COUNT, 06953 AST_REDIRECTING_FROM_SUBADDRESS, 06954 AST_REDIRECTING_FROM_SUBADDRESS_TYPE, 06955 AST_REDIRECTING_FROM_SUBADDRESS_ODD_EVEN, 06956 AST_REDIRECTING_FROM_SUBADDRESS_VALID, 06957 AST_REDIRECTING_TO_SUBADDRESS, 06958 AST_REDIRECTING_TO_SUBADDRESS_TYPE, 06959 AST_REDIRECTING_TO_SUBADDRESS_ODD_EVEN, 06960 AST_REDIRECTING_TO_SUBADDRESS_VALID 06961 };
| int __ast_answer | ( | struct ast_channel * | chan, | |
| unsigned int | delay, | |||
| int | cdr_answer | |||
| ) |
Answer a channel, with a selectable delay before returning.
| 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 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.
| 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.
| NULL | failure | |
| non-NULL | successfully allocated channel |
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] |
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.
| 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 |
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 __init_state2str_threadbuf | ( | void | ) | [static] |
| 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
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.
| chan | channel to answer |
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.
| 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.
| 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.
| chan | Current 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.
| chan | which channel to make the call on | |
| addr | destination of the call | |
| timeout | time to wait on for connect |
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.
| 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) |
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.
| chan | the channel to change the name of | |
| newname | the name to change to |
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.
| c0 | first channel to bridge | |
| c1 | second channel to bridge | |
| config | config for the channels | |
| fo | destination frame(?) | |
| rc | destination channel(?) |
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.
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.
| chan | channel on which to check for hang up | |
| offset | offset in seconds from current time |
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.
| 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. |
| 0 | Success | |
| -1 | Either the macro does not exist, or there was an error while attempting to run the macro |
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, ¯o_chan->connected); 07393 } else { 07394 ast_party_connected_line_copy(¯o_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, ¯o_chan->connected); 07399 } 07400 07401 return retval; 07402 }
| int ast_channel_datastore_add | ( | struct ast_channel * | chan, | |
| struct ast_datastore * | datastore | |||
| ) |
Add a datastore to a channel.
| 0 | success | |
| non-zero | failure |
Definition at line 1969 of file channel.c.
References AST_LIST_INSERT_HEAD, and ast_channel::datastores.
Referenced by _macro_exec(), acf_curlopt_write(), acf_iaxvar_write(), acf_odbc_read(), add_features_datastores(), add_to_agi(), ast_iax2_new(), audiohook_volume_get(), authenticate_reply(), calendar_query_exec(), dial_exec_full(), do_notify(), dundi_query_read(), enable_jack_hook(), enum_query_read(), find_transaction(), get_lock(), gosub_exec(), lua_get_state(), mute_add_audiohook(), pbx_builtin_raise_exception(), setup_inheritance_datastore(), setup_mixmonitor_ds(), setup_transfer_datastore(), shared_write(), smdi_msg_retrieve_read(), socket_process(), speech_create(), speex_write(), try_calling(), and volume_write().
01970 { 01971 int res = 0; 01972 01973 AST_LIST_INSERT_HEAD(&chan->datastores, datastore, entry); 01974 01975 return res; 01976 }
| struct ast_datastore* ast_channel_datastore_alloc | ( | const struct ast_datastore_info * | info, | |
| const char * | uid | |||
| ) | [read] |
Create a channel data store object.
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.
The datastore returned from this function must not be used if the reference to the channel is released.
| 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.
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.
| 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).
| c0 | first channel to bridge | |
| c1 | second channel to bridge |
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.
| a | channel that is at the specified extension and context | |
| NULL | if no channel was found |
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] |
Find a channel by name.
Channel search functions
| a | channel with the name specified by the argument | |
| NULL | if no channel was found |
Definition at line 1397 of file channel.c.
References ast_channel_get_full().
Referenced by action_add_agi_cmd(), action_atxfer(), action_getvar(), action_hangup(), action_redirect(), action_sendtext(), action_setvar(), action_status(), action_timeout(), ast_async_goto_by_name(), ast_bridge_call(), asyncgoto_exec(), change_monitor_action(), do_pause_or_unpause(), func_mchan_read(), func_mchan_write(), handle_channelstatus(), handle_cli_agi_add_cmd(), handle_core_set_debug_channel(), handle_getvariablefull(), handle_hangup(), handle_redirect(), handle_set_chanvar(), handle_show_chanvar(), handle_showchan(), handle_softhangup(), import_helper(), manager_mutestream(), manager_park(), manager_play_dtmf(), park_call_full(), pbx_builtin_importvar(), shared_read(), shared_write(), start_monitor_action(), and stop_monitor_action().
01398 { 01399 return ast_channel_get_full(name, 0, NULL, NULL); 01400 }
| struct ast_channel* ast_channel_get_by_name_prefix | ( | const char * | name, | |
| size_t | name_len | |||
| ) | [read] |
Find a channel by a name prefix.
| a | channel with the name prefix specified by the arguments | |
| NULL | if no channel was found |
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.
| parent | Parent channel | |
| child | Child channel |
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.
| NULL | on failure | |
| a | new channel iterator |
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.
| NULL | on failure | |
| a | new channel iterator based on the specified parameters |
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.
| NULL | on failure | |
| a | new channel iterator based on the specified parameters |
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.
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.
| the | next channel that matches the parameters used when the iterator was created. | |
| NULL,if | no more channels match the iterator parameters. |
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.
| c0 | first channel to make compatible | |
| c1 | other channel to make compatible |
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.
| original | channel to make a copy of | |
| clone | copy of the original channel |
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.
| chan | Asterisk channel to indicate connected line information | |
| connected | Connected line information |
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.
| chan | Asterisk channel to indicate redirecting id information | |
| redirecting | Redirecting id information |
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
| reason | The integer argument, usually taken from AST_CONTROL_ macros |
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.
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.
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.
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.
| chan | Asterisk channel to set connected line information | |
| connected | Connected line information |
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.
| chan | Asterisk channel to set redirecting id information | |
| redirecting | Redirecting id information |
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.
| channel | channel to set options on | |
| option | option to change | |
| data | data specific to option | |
| datalen | length of the data | |
| block | blocking or not |
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.
| chan | channel on which to check for hang up | |
| offset | offset in seconds relative to the current time of when to hang up |
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.
| chan | The channel to generate silence on |
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.
| chan | The channel to operate on | |
| state | The ast_silence_generator pointer return by a previous call to ast_channel_start_silence_generator. |
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.
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().
| 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.
| chan | Asterisk channel to indicate connected line information | |
| connected | Connected line information |
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.
| chan | Asterisk channel to indicate redirecting id information | |
| redirecting | Redirecting id information |
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 | ) |
Provided by channel.c
Definition at line 6366 of file channel.c.
References ao2_container_alloc, ARRAY_LEN, ast_channel_cmp_cb(), ast_channel_hash_cb(), ast_cli_register_multiple(), channels, cli_channel, and NUM_CHANNEL_BUCKETS.
Referenced by main().
06367 { 06368 channels = ao2_container_alloc(NUM_CHANNEL_BUCKETS, 06369 ast_channel_hash_cb, ast_channel_cmp_cb); 06370 06371 ast_cli_register_multiple(cli_channel, ARRAY_LEN(cli_channel)); 06372 }
| 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.
| data | Buffer to fill with the frame data | |
| datalen | Size of the buffer to fill | |
| connected | Connected line information |
| -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.
| dest | Destination connected line information | |
| src | Source caller information |
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.
| dest | Destination caller information | |
| src | Source connected line information |
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.
| data | Buffer with the frame data to parse | |
| datalen | Size of the buffer | |
| connected | Extracted connected line information |
| 0 | on success. | |
| -1 | on error. |
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 | ) |
Deactivate an active generator
Definition at line 2420 of file channel.c.
References ast_channel_lock, ast_channel_set_fd(), ast_channel_unlock, ast_clear_flag, AST_FLAG_WRITE_INT, AST_GENERATOR_FD, ast_settimeout(), ast_channel::generator, ast_channel::generatordata, and ast_generator::release.
Referenced by __ast_read(), app_exec(), ast_channel_stop_silence_generator(), ast_openstream_full(), ast_playtones_stop(), ast_quiet_chan(), ast_read_generator_actions(), ast_tonepair_stop(), ast_write(), cb_events(), channel_spy(), dial_exec_full(), generator_force(), local_ast_moh_stop(), old_milliwatt_exec(), transmit_audio(), and wait_for_answer().
02421 { 02422 ast_channel_lock(chan); 02423 if (chan->generatordata) { 02424 if (chan->generator && chan->generator->release) 02425 chan->generator->release(chan, chan->generatordata); 02426 chan->generatordata = NULL; 02427 chan->generator = NULL; 02428 ast_channel_set_fd(chan, AST_GENERATOR_FD, -1); 02429 ast_clear_flag(chan, AST_FLAG_WRITE_INT); 02430 ast_settimeout(chan, 0, NULL, NULL); 02431 } 02432 ast_channel_unlock(chan); 02433 }
| int ast_do_masquerade | ( | struct ast_channel * | original | ) |
Masquerade a channel.
Start masquerading a channel.
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.
| NULL | failure | |
| non-NULL | successfully allocated channel |
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 | |||
| ) |
Indicates condition of channel.
| chan | channel to change the indication | |
| condition | which condition to indicate on the channel |
Definition at line 3551 of file channel.c.
References ast_indicate_data().
Referenced by __ast_play_and_record(), agent_new(), alsa_call(), analog_attempt_transfer(), answer_trunk_chan(), ast_bridge_call(), ast_channel_bridge(), ast_do_masquerade(), ast_dtmf_stream(), ast_raw_answer(), attempt_transfer(), builtin_atxfer(), builtin_blindtransfer(), cli_console_answer(), conf_run(), console_call(), dial_exec_full(), disa_exec(), do_forward(), feature_request_and_dial(), finishup(), function_remote(), handle_callforward_button(), handle_frame(), handle_recordfile(), manage_parkinglot(), mgcp_ss(), monitor_dial(), oss_call(), park_call_full(), park_exec_full(), pbx_builtin_busy(), pbx_builtin_congestion(), pbx_builtin_proceeding(), pbx_builtin_progress(), pbx_builtin_ringing(), pbx_builtin_waitexten(), queue_exec(), record_exec(), rpt(), rpt_exec(), say_periodic_announcement(), say_position(), send_waveform_to_channel(), skinny_ss(), sla_handle_hold_event(), sla_station_exec(), sla_trunk_exec(), try_calling(), and wait_for_answer().
03552 { 03553 return ast_indicate_data(chan, condition, NULL, 0); 03554 }
| int ast_indicate_data | ( | struct ast_channel * | chan, | |
| int | condition, | |||
| const void * | data, | |||
| size_t | datalen | |||
| ) |
Indicates condition of channel, with payload.
| chan | channel to change the indication | |
| condition | which condition to indicate on the channel | |
| data | pointer to payload data | |
| datalen | size of payload data |
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 }
<